aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.drone.yml3
-rw-r--r--.gitignore4
-rw-r--r--compiler/sjs/backend/sjs/JSCodeGen.scala64
-rw-r--r--compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala38
-rw-r--r--compiler/src/dotty/tools/backend/jvm/scalaPrimitives.scala6
-rw-r--r--compiler/src/dotty/tools/dotc/Compiler.scala1
-rw-r--r--compiler/src/dotty/tools/dotc/ast/Desugar.scala80
-rw-r--r--compiler/src/dotty/tools/dotc/ast/TreeInfo.scala12
-rw-r--r--compiler/src/dotty/tools/dotc/ast/Trees.scala17
-rw-r--r--compiler/src/dotty/tools/dotc/ast/tpd.scala3
-rw-r--r--compiler/src/dotty/tools/dotc/ast/untpd.scala10
-rw-r--r--compiler/src/dotty/tools/dotc/config/Config.scala4
-rw-r--r--compiler/src/dotty/tools/dotc/config/JavaPlatform.scala1
-rw-r--r--compiler/src/dotty/tools/dotc/config/PathResolver.scala2
-rw-r--r--compiler/src/dotty/tools/dotc/config/ScalaSettings.scala2
-rw-r--r--compiler/src/dotty/tools/dotc/core/Comments.scala2
-rw-r--r--compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala1
-rw-r--r--compiler/src/dotty/tools/dotc/core/Contexts.scala23
-rw-r--r--compiler/src/dotty/tools/dotc/core/Definitions.scala274
-rw-r--r--compiler/src/dotty/tools/dotc/core/Denotations.scala22
-rw-r--r--compiler/src/dotty/tools/dotc/core/NameOps.scala11
-rw-r--r--compiler/src/dotty/tools/dotc/core/Periods.scala2
-rw-r--r--compiler/src/dotty/tools/dotc/core/Phases.scala5
-rw-r--r--compiler/src/dotty/tools/dotc/core/Scopes.scala2
-rw-r--r--compiler/src/dotty/tools/dotc/core/StdNames.scala4
-rw-r--r--compiler/src/dotty/tools/dotc/core/SymDenotations.scala13
-rw-r--r--compiler/src/dotty/tools/dotc/core/Symbols.scala35
-rw-r--r--compiler/src/dotty/tools/dotc/core/TypeComparer.scala52
-rw-r--r--compiler/src/dotty/tools/dotc/core/TypeErasure.scala36
-rw-r--r--compiler/src/dotty/tools/dotc/core/TypeOps.scala27
-rw-r--r--compiler/src/dotty/tools/dotc/core/Types.scala64
-rw-r--r--compiler/src/dotty/tools/dotc/parsing/JavaParsers.scala3
-rw-r--r--compiler/src/dotty/tools/dotc/parsing/Parsers.scala320
-rw-r--r--compiler/src/dotty/tools/dotc/parsing/Scanners.scala2
-rw-r--r--compiler/src/dotty/tools/dotc/parsing/Tokens.scala2
-rw-r--r--compiler/src/dotty/tools/dotc/printing/Formatting.scala5
-rw-r--r--compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala2
-rw-r--r--compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala15
-rw-r--r--compiler/src/dotty/tools/dotc/repl/CompilingInterpreter.scala76
-rw-r--r--compiler/src/dotty/tools/dotc/repl/InterpreterLoop.scala2
-rw-r--r--compiler/src/dotty/tools/dotc/reporting/Reporter.scala9
-rw-r--r--compiler/src/dotty/tools/dotc/reporting/StoreReporter.scala8
-rw-r--r--compiler/src/dotty/tools/dotc/reporting/diagnostic/MessageContainer.scala2
-rw-r--r--compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala111
-rw-r--r--compiler/src/dotty/tools/dotc/sbt/ExtractAPI.scala30
-rw-r--r--compiler/src/dotty/tools/dotc/transform/CollectEntryPoints.scala1
-rw-r--r--compiler/src/dotty/tools/dotc/transform/ElimByName.scala3
-rw-r--r--compiler/src/dotty/tools/dotc/transform/Erasure.scala90
-rw-r--r--compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala51
-rw-r--r--compiler/src/dotty/tools/dotc/transform/ExtensionMethods.scala8
-rw-r--r--compiler/src/dotty/tools/dotc/transform/InterceptedMethods.scala18
-rw-r--r--compiler/src/dotty/tools/dotc/transform/LazyVals.scala2
-rw-r--r--compiler/src/dotty/tools/dotc/transform/LiftTry.scala2
-rw-r--r--compiler/src/dotty/tools/dotc/transform/Memoize.scala36
-rw-r--r--compiler/src/dotty/tools/dotc/transform/ParamForwarding.scala4
-rw-r--r--compiler/src/dotty/tools/dotc/transform/PatternMatcher.scala61
-rw-r--r--compiler/src/dotty/tools/dotc/transform/ShortcutImplicits.scala165
-rw-r--r--compiler/src/dotty/tools/dotc/transform/SuperAccessors.scala33
-rw-r--r--compiler/src/dotty/tools/dotc/transform/TreeChecker.scala7
-rw-r--r--compiler/src/dotty/tools/dotc/transform/TreeTransform.scala10
-rw-r--r--compiler/src/dotty/tools/dotc/transform/ValueClasses.scala10
-rw-r--r--compiler/src/dotty/tools/dotc/typer/Applications.scala163
-rw-r--r--compiler/src/dotty/tools/dotc/typer/Checking.scala56
-rw-r--r--compiler/src/dotty/tools/dotc/typer/Dynamic.scala11
-rw-r--r--compiler/src/dotty/tools/dotc/typer/ErrorReporting.scala14
-rw-r--r--compiler/src/dotty/tools/dotc/typer/FrontEnd.scala24
-rw-r--r--compiler/src/dotty/tools/dotc/typer/Implicits.scala191
-rw-r--r--compiler/src/dotty/tools/dotc/typer/ImportInfo.scala16
-rw-r--r--compiler/src/dotty/tools/dotc/typer/Inferencing.scala16
-rw-r--r--compiler/src/dotty/tools/dotc/typer/Inliner.scala2
-rw-r--r--compiler/src/dotty/tools/dotc/typer/Namer.scala132
-rw-r--r--compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala31
-rw-r--r--compiler/src/dotty/tools/dotc/typer/ReTyper.scala5
-rw-r--r--compiler/src/dotty/tools/dotc/typer/RefChecks.scala42
-rw-r--r--compiler/src/dotty/tools/dotc/typer/TypeAssigner.scala22
-rw-r--r--compiler/src/dotty/tools/dotc/typer/Typer.scala263
-rw-r--r--compiler/src/dotty/tools/dotc/util/Chars.scala9
-rw-r--r--compiler/test/dotc/scala-collections.blacklist83
-rw-r--r--compiler/test/dotc/scala-collections.whitelist350
-rw-r--r--compiler/test/dotc/tests.scala71
-rw-r--r--compiler/test/dotty/Jars.scala6
-rw-r--r--compiler/test/dotty/tools/dotc/CompilerTest.scala5
-rw-r--r--compiler/test/dotty/tools/dotc/parsing/ModifiersParsingTest.scala6
-rw-r--r--compiler/test/dotty/tools/dotc/transform/PatmatExhaustivityTest.scala4
-rw-r--r--doc-tool/src/dotty/tools/dottydoc/core/DocASTPhase.scala52
-rw-r--r--doc-tool/src/dotty/tools/dottydoc/model/factories.scala15
-rw-r--r--doc-tool/test/BaseTest.scala2
-rw-r--r--docs/blog/_posts/2016-12-05-implicit-function-types.md364
-rw-r--r--docs/docs/contributing/workflow.md4
-rw-r--r--docs/docs/index.md1
-rw-r--r--docs/docs/internals/backend.md28
-rw-r--r--docs/docs/internals/overall-structure.md31
-rw-r--r--docs/docs/internals/syntax.md356
-rw-r--r--docs/dotc-internals/core-data-structures.md113
-rw-r--r--docs/syntax-summary.txt329
-rw-r--r--library/src/dotty/Show.scala102
-rw-r--r--library/src/scala/Function23.scala21
-rw-r--r--library/src/scala/Function24.scala21
-rw-r--r--library/src/scala/Function25.scala21
-rw-r--r--library/src/scala/Function26.scala20
-rw-r--r--library/src/scala/Function27.scala20
-rw-r--r--library/src/scala/Function28.scala20
-rw-r--r--library/src/scala/Function29.scala20
-rw-r--r--library/src/scala/Function30.scala20
-rw-r--r--library/src/scala/FunctionXXL.scala9
-rw-r--r--library/test/dotty/ShowTests.scala69
-rw-r--r--project/Build.scala61
-rw-r--r--sbt-bridge/sbt-test/compilerReporter/simple/project/DottyInjectedPlugin.scala4
-rw-r--r--sbt-bridge/sbt-test/discovery/test-discovery/build.sbt1
-rw-r--r--sbt-bridge/sbt-test/discovery/test-discovery/changes/A2.scala3
-rw-r--r--sbt-bridge/sbt-test/discovery/test-discovery/project/DottyInjectedPlugin.scala17
-rw-r--r--sbt-bridge/sbt-test/discovery/test-discovery/src/main/scala/A.scala3
-rw-r--r--sbt-bridge/sbt-test/discovery/test-discovery/src/test/scala/TestA.scala8
-rw-r--r--sbt-bridge/sbt-test/discovery/test-discovery/test8
-rw-r--r--sbt-bridge/sbt-test/source-dependencies/abstract-override/project/DottyInjectedPlugin.scala4
-rw-r--r--sbt-bridge/sbt-test/source-dependencies/abstract-type-override/project/DottyInjectedPlugin.scala4
-rw-r--r--sbt-bridge/sbt-test/source-dependencies/abstract-type/project/DottyInjectedPlugin.scala4
-rw-r--r--sbt-bridge/sbt-test/source-dependencies/added/project/DottyInjectedPlugin.scala4
-rw-r--r--sbt-bridge/sbt-test/source-dependencies/as-seen-from-a/project/DottyInjectedPlugin.scala4
-rw-r--r--sbt-bridge/sbt-test/source-dependencies/as-seen-from-b/project/DottyInjectedPlugin.scala4
-rw-r--r--sbt-bridge/sbt-test/source-dependencies/backtick-quoted-names/project/DottyInjectedPlugin.scala4
-rw-r--r--sbt-bridge/sbt-test/source-dependencies/binary/project/DottyInjectedPlugin.scala4
-rw-r--r--sbt-bridge/sbt-test/source-dependencies/by-name/project/DottyInjectedPlugin.scala4
-rw-r--r--sbt-bridge/sbt-test/source-dependencies/canon/project/DottyInjectedPlugin.scala4
-rw-r--r--sbt-bridge/sbt-test/source-dependencies/compactify/project/DottyInjectedPlugin.scala4
-rw-r--r--sbt-bridge/sbt-test/source-dependencies/constants/project/DottyInjectedPlugin.scala4
-rw-r--r--sbt-bridge/sbt-test/source-dependencies/default-params/project/DottyInjectedPlugin.scala4
-rw-r--r--sbt-bridge/sbt-test/source-dependencies/dup-class/project/DottyInjectedPlugin.scala4
-rw-r--r--sbt-bridge/sbt-test/source-dependencies/empty-a/project/DottyInjectedPlugin.scala4
-rw-r--r--sbt-bridge/sbt-test/source-dependencies/empty-package/project/DottyInjectedPlugin.scala4
-rw-r--r--sbt-bridge/sbt-test/source-dependencies/erasure/project/DottyInjectedPlugin.scala4
-rw-r--r--sbt-bridge/sbt-test/source-dependencies/export-jars/project/DottyInjectedPlugin.scala4
-rw-r--r--sbt-bridge/sbt-test/source-dependencies/ext/project/DottyInjectedPlugin.scala4
-rw-r--r--sbt-bridge/sbt-test/source-dependencies/false-error/project/DottyInjectedPlugin.scala4
-rw-r--r--sbt-bridge/sbt-test/source-dependencies/fbounded-existentials/project/DottyInjectedPlugin.scala4
-rw-r--r--sbt-bridge/sbt-test/source-dependencies/implicit-params/project/DottyInjectedPlugin.scala4
-rw-r--r--sbt-bridge/sbt-test/source-dependencies/implicit-search-companion-scope/project/DottyInjectedPlugin.scala4
-rw-r--r--sbt-bridge/sbt-test/source-dependencies/implicit-search/project/DottyInjectedPlugin.scala4
-rw-r--r--sbt-bridge/sbt-test/source-dependencies/implicit/project/DottyInjectedPlugin.scala4
-rw-r--r--sbt-bridge/sbt-test/source-dependencies/import-class/project/DottyInjectedPlugin.scala4
-rw-r--r--sbt-bridge/sbt-test/source-dependencies/import-package/project/DottyInjectedPlugin.scala4
-rw-r--r--sbt-bridge/sbt-test/source-dependencies/inherited-deps-java/project/DottyInjectedPlugin.scala4
-rw-r--r--sbt-bridge/sbt-test/source-dependencies/inherited_type_params/project/DottyInjectedPlugin.scala4
-rw-r--r--sbt-bridge/sbt-test/source-dependencies/inline/project/DottyInjectedPlugin.scala4
-rw-r--r--sbt-bridge/sbt-test/source-dependencies/intermediate-error/project/DottyInjectedPlugin.scala4
-rw-r--r--sbt-bridge/sbt-test/source-dependencies/java-analysis-serialization-error/project/DottyInjectedPlugin.scala4
-rw-r--r--sbt-bridge/sbt-test/source-dependencies/java-basic/project/DottyInjectedPlugin.scala4
-rw-r--r--sbt-bridge/sbt-test/source-dependencies/java-generic-workaround/project/DottyInjectedPlugin.scala4
-rw-r--r--sbt-bridge/sbt-test/source-dependencies/java-mixed/project/DottyInjectedPlugin.scala4
-rw-r--r--sbt-bridge/sbt-test/source-dependencies/java-static/project/DottyInjectedPlugin.scala4
-rw-r--r--sbt-bridge/sbt-test/source-dependencies/lazy-val/project/DottyInjectedPlugin.scala4
-rw-r--r--sbt-bridge/sbt-test/source-dependencies/less-inter-inv-java/project/DottyInjectedPlugin.scala4
-rw-r--r--sbt-bridge/sbt-test/source-dependencies/less-inter-inv/project/DottyInjectedPlugin.scala4
-rw-r--r--sbt-bridge/sbt-test/source-dependencies/linearization/project/DottyInjectedPlugin.scala4
-rw-r--r--sbt-bridge/sbt-test/source-dependencies/named/project/DottyInjectedPlugin.scala4
-rw-r--r--sbt-bridge/sbt-test/source-dependencies/nested-case-class/project/DottyInjectedPlugin.scala4
-rw-r--r--sbt-bridge/sbt-test/source-dependencies/new-cyclic/project/DottyInjectedPlugin.scala4
-rw-r--r--sbt-bridge/sbt-test/source-dependencies/new-pkg-dep/project/DottyInjectedPlugin.scala4
-rw-r--r--sbt-bridge/sbt-test/source-dependencies/override/project/DottyInjectedPlugin.scala4
-rw-r--r--sbt-bridge/sbt-test/source-dependencies/parent-change/project/DottyInjectedPlugin.scala4
-rw-r--r--sbt-bridge/sbt-test/source-dependencies/parent-member-change/project/DottyInjectedPlugin.scala4
-rw-r--r--sbt-bridge/sbt-test/source-dependencies/pkg-self/project/DottyInjectedPlugin.scala4
-rw-r--r--sbt-bridge/sbt-test/source-dependencies/qualified-access/project/DottyInjectedPlugin.scala4
-rw-r--r--sbt-bridge/sbt-test/source-dependencies/relative-source-error/project/DottyInjectedPlugin.scala4
-rw-r--r--sbt-bridge/sbt-test/source-dependencies/remove-test-a/project/DottyInjectedPlugin.scala4
-rw-r--r--sbt-bridge/sbt-test/source-dependencies/remove-test-b/project/DottyInjectedPlugin.scala4
-rw-r--r--sbt-bridge/sbt-test/source-dependencies/repeated-parameters/project/DottyInjectedPlugin.scala4
-rw-r--r--sbt-bridge/sbt-test/source-dependencies/replace-test-a/project/DottyInjectedPlugin.scala4
-rw-r--r--sbt-bridge/sbt-test/source-dependencies/resident-java/project/DottyInjectedPlugin.scala4
-rw-r--r--sbt-bridge/sbt-test/source-dependencies/resident-package-object/project/DottyInjectedPlugin.scala4
-rw-r--r--sbt-bridge/sbt-test/source-dependencies/restore-classes/project/DottyInjectedPlugin.scala4
-rw-r--r--sbt-bridge/sbt-test/source-dependencies/same-file-used-names/project/DottyInjectedPlugin.scala4
-rw-r--r--sbt-bridge/sbt-test/source-dependencies/sealed/project/DottyInjectedPlugin.scala4
-rw-r--r--sbt-bridge/sbt-test/source-dependencies/signature-change/project/DottyInjectedPlugin.scala4
-rw-r--r--sbt-bridge/sbt-test/source-dependencies/specialized/project/DottyInjectedPlugin.scala4
-rw-r--r--sbt-bridge/sbt-test/source-dependencies/stability-change/project/DottyInjectedPlugin.scala4
-rw-r--r--sbt-bridge/sbt-test/source-dependencies/synthetic-companion/project/DottyInjectedPlugin.scala4
-rw-r--r--sbt-bridge/sbt-test/source-dependencies/trait-member-modified/project/DottyInjectedPlugin.scala4
-rw-r--r--sbt-bridge/sbt-test/source-dependencies/trait-private-object/project/DottyInjectedPlugin.scala4
-rw-r--r--sbt-bridge/sbt-test/source-dependencies/trait-private-var/project/DottyInjectedPlugin.scala4
-rw-r--r--sbt-bridge/sbt-test/source-dependencies/trait-super/project/DottyInjectedPlugin.scala4
-rw-r--r--sbt-bridge/sbt-test/source-dependencies/transitive-a/project/DottyInjectedPlugin.scala4
-rw-r--r--sbt-bridge/sbt-test/source-dependencies/transitive-b/project/DottyInjectedPlugin.scala4
-rw-r--r--sbt-bridge/sbt-test/source-dependencies/transitive-inherit-java/project/DottyInjectedPlugin.scala4
-rw-r--r--sbt-bridge/sbt-test/source-dependencies/transitive-inherit/project/DottyInjectedPlugin.scala4
-rw-r--r--sbt-bridge/sbt-test/source-dependencies/transitive-memberRef/project/DottyInjectedPlugin.scala4
-rw-r--r--sbt-bridge/sbt-test/source-dependencies/type-alias/project/DottyInjectedPlugin.scala4
-rw-r--r--sbt-bridge/sbt-test/source-dependencies/type-parameter/project/DottyInjectedPlugin.scala4
-rw-r--r--sbt-bridge/sbt-test/source-dependencies/typeref-only/project/DottyInjectedPlugin.scala4
-rw-r--r--sbt-bridge/sbt-test/source-dependencies/typeref-return/project/DottyInjectedPlugin.scala4
-rw-r--r--sbt-bridge/sbt-test/source-dependencies/types-in-used-names-a/project/DottyInjectedPlugin.scala4
-rw-r--r--sbt-bridge/sbt-test/source-dependencies/types-in-used-names-b/project/DottyInjectedPlugin.scala4
-rw-r--r--sbt-bridge/sbt-test/source-dependencies/value-class/project/DottyInjectedPlugin.scala4
-rw-r--r--sbt-bridge/sbt-test/source-dependencies/var/project/DottyInjectedPlugin.scala4
-rw-r--r--sbt-bridge/sbt-test/source-dependencies/variance/project/DottyInjectedPlugin.scala4
-rwxr-xr-xscripts/jobs/validate/junit3
-rwxr-xr-xscripts/jobs/validate/partest3
-rwxr-xr-xscripts/jobs/validate/partest-bootstrapped3
-rwxr-xr-xscripts/update-scala-library5
-rw-r--r--tests/bench/transactional/Benchmark.scala5
-rw-r--r--tests/bench/transactional/ImplicitMega.scala67
-rw-r--r--tests/bench/transactional/ImplicitMono.scala45
-rw-r--r--tests/bench/transactional/ReaderMonadic.scala87
-rw-r--r--tests/bench/transactional/Runner.scala25
-rw-r--r--tests/bench/transactional/Transaction.scala21
-rw-r--r--tests/bench/transactional/results.md77
-rw-r--r--tests/neg/i1639.scala10
-rw-r--r--tests/neg/i1642.scala1
-rw-r--r--tests/neg/i1647.scala4
-rw-r--r--tests/neg/i1649.scala2
-rw-r--r--tests/neg/i1670.scala1
-rw-r--r--tests/neg/i1707.scala24
-rw-r--r--tests/neg/i1716.scala9
-rw-r--r--tests/neg/i1779.scala13
-rw-r--r--tests/neg/i1786.scala17
-rw-r--r--tests/neg/i1793.scala7
-rw-r--r--tests/neg/i1802.scala21
-rw-r--r--tests/neg/i1806.scala7
-rw-r--r--tests/neg/i1845.scala3
-rw-r--r--tests/neg/i705-inner-value-class2.scala2
-rw-r--r--tests/neg/implicitDefs.scala7
-rw-r--r--tests/neg/nopredef.scala5
-rw-r--r--tests/neg/t3683-modified.scala20
-rw-r--r--tests/pending/pos/i1535.scala9
-rw-r--r--tests/pending/pos/i1710.scala11
-rw-r--r--tests/pending/run/i1732.scala8
-rw-r--r--tests/pickling/extmethods.scala1
-rw-r--r--tests/pos-java-interop/innerClass/Outer.scala8
-rw-r--r--tests/pos-java-interop/innerClass/Test.java9
-rw-r--r--tests/pos-scala2/i1792.scala8
-rw-r--r--tests/pos/Monoid.scala61
-rw-r--r--tests/pos/Patterns.scala28
-rw-r--r--tests/pos/functionXXL.scala72
-rw-r--r--tests/pos/hkwild.scala6
-rw-r--r--tests/pos/i1540.scala4
-rw-r--r--tests/pos/i1540b.scala4
-rw-r--r--tests/pos/i1642.scala2
-rw-r--r--tests/pos/i1665.scala7
-rw-r--r--tests/pos/i1704.scala4
-rw-r--r--tests/pos/i1737.scala11
-rw-r--r--tests/pos/i1751.scala17
-rw-r--r--tests/pos/i1753.scala22
-rw-r--r--tests/pos/i1755.scala21
-rw-r--r--tests/pos/i1756.scala20
-rw-r--r--tests/pos/i1757.scala6
-rw-r--r--tests/pos/i1765.scala21
-rw-r--r--tests/pos/i1776.scala3
-rw-r--r--tests/pos/i1777.scala9
-rw-r--r--tests/pos/i1786.scala18
-rw-r--r--tests/pos/i1790.scala15
-rw-r--r--tests/pos/i1793.scala7
-rw-r--r--tests/pos/i1795.scala13
-rw-r--r--tests/pos/i1797.scala1
-rw-r--r--tests/pos/i1803.scala7
-rw-r--r--tests/pos/i1812.scala12
-rw-r--r--tests/pos/i1812b.scala11
-rw-r--r--tests/pos/i1865.scala24
-rw-r--r--tests/pos/i1867.scala3
-rw-r--r--tests/pos/i1868.scala7
-rw-r--r--tests/pos/i1891.scala11
-rw-r--r--tests/pos/implicits.scala5
-rw-r--r--tests/pos/lazyValsSepComp.scala2
-rw-r--r--tests/pos/pos_valueclasses/optmatch.scala2
-rw-r--r--tests/repl/def.check13
-rw-r--r--tests/repl/import.check8
-rw-r--r--tests/repl/imports.check4
-rw-r--r--tests/repl/innerClasses.check5
-rw-r--r--tests/repl/onePlusOne.check2
-rw-r--r--tests/repl/patdef.check14
-rw-r--r--tests/repl/toplevelTry.check2
-rw-r--r--tests/repl/vars.check4
-rw-r--r--tests/run/final-var.check4
-rw-r--r--tests/run/final-var.scala20
-rw-r--r--tests/run/i1732.scala15
-rw-r--r--tests/run/i1748.check2
-rw-r--r--tests/run/i1748.scala14
-rw-r--r--tests/run/i1773.check2
-rw-r--r--tests/run/i1773.scala14
-rw-r--r--tests/run/i1779.check1
-rw-r--r--tests/run/i1779.scala13
-rw-r--r--tests/run/i1820.check1
-rw-r--r--tests/run/i1820.scala17
-rw-r--r--tests/run/i1820b.check1
-rw-r--r--tests/run/i1820b.scala19
-rw-r--r--tests/run/implicitFuns.scala261
285 files changed, 5334 insertions, 1603 deletions
diff --git a/.drone.yml b/.drone.yml
index 9da1e75fa..0b927794e 100644
--- a/.drone.yml
+++ b/.drone.yml
@@ -1,9 +1,10 @@
pipeline:
test:
- image: lampepfl/dotty:0.1
+ image: lampepfl/dotty:latest
pull: true
commands:
- ln -s /var/cache/drone/scala-scala scala-scala
+ - ./scripts/update-scala-library
- sbt -Ddotty.drone.mem=4096m -ivy /var/cache/drone/ivy2 "${TEST}"
matrix:
diff --git a/.gitignore b/.gitignore
index 9d9f8fa3b..1a0b1b6a7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -49,3 +49,7 @@ build/
.packages
/.cache-main
/.cache-tests
+
+# Put local stuff here
+local/
+
diff --git a/compiler/sjs/backend/sjs/JSCodeGen.scala b/compiler/sjs/backend/sjs/JSCodeGen.scala
index 401e01784..69a5651fc 100644
--- a/compiler/sjs/backend/sjs/JSCodeGen.scala
+++ b/compiler/sjs/backend/sjs/JSCodeGen.scala
@@ -127,7 +127,7 @@ class JSCodeGen()(implicit ctx: Context) {
/* Finally, we emit true code for the remaining class defs. */
for (td <- allTypeDefs) {
val sym = td.symbol
- implicit val pos: Position = sym.pos
+ implicit val pos = sym.pos
/* Do not actually emit code for primitive types nor scala.Array. */
val isPrimitive =
@@ -203,7 +203,7 @@ class JSCodeGen()(implicit ctx: Context) {
*/
private def genScalaClass(td: TypeDef): js.ClassDef = {
val sym = td.symbol.asClass
- implicit val pos: Position = sym.pos
+ implicit val pos = sym.pos
assert(!sym.is(Trait),
"genScalaClass() must be called only for normal classes: "+sym)
@@ -336,7 +336,7 @@ class JSCodeGen()(implicit ctx: Context) {
*/
private def genRawJSClassData(td: TypeDef): js.ClassDef = {
val sym = td.symbol.asClass
- implicit val pos: Position = sym.pos
+ implicit val pos = sym.pos
val classIdent = encodeClassFullNameIdent(sym)
val superClass =
@@ -358,7 +358,7 @@ class JSCodeGen()(implicit ctx: Context) {
*/
private def genInterface(td: TypeDef): js.ClassDef = {
val sym = td.symbol.asClass
- implicit val pos: Position = sym.pos
+ implicit val pos = sym.pos
val classIdent = encodeClassFullNameIdent(sym)
@@ -408,7 +408,7 @@ class JSCodeGen()(implicit ctx: Context) {
f <- classSym.info.decls
if !f.is(Method) && f.isTerm
} yield {
- implicit val pos: Position = f.pos
+ implicit val pos = f.pos
val name =
/*if (isExposed(f)) js.StringLiteral(jsNameOf(f))
@@ -479,7 +479,7 @@ class JSCodeGen()(implicit ctx: Context) {
* Other (normal) methods are emitted with `genMethodBody()`.
*/
private def genMethodWithCurrentLocalNameScope(dd: DefDef): Option[js.MethodDef] = {
- implicit val pos: Position = dd.pos
+ implicit val pos = dd.pos
val sym = dd.symbol
val vparamss = dd.vparamss
val rhs = dd.rhs
@@ -501,7 +501,7 @@ class JSCodeGen()(implicit ctx: Context) {
val methodName: js.PropertyName = encodeMethodSym(sym)
def jsParams = for (param <- params) yield {
- implicit val pos: Position = param.pos
+ implicit val pos = param.pos
js.ParamDef(encodeLocalSym(param), toIRType(param.info),
mutable = false, rest = false)
}
@@ -574,13 +574,13 @@ class JSCodeGen()(implicit ctx: Context) {
private def genMethodDef(static: Boolean, methodName: js.PropertyName,
paramsSyms: List[Symbol], resultIRType: jstpe.Type,
tree: Tree, optimizerHints: OptimizerHints): js.MethodDef = {
- implicit val pos: Position = tree.pos
+ implicit val pos = tree.pos
ctx.debuglog("genMethod " + methodName.name)
ctx.debuglog("")
val jsParams = for (param <- paramsSyms) yield {
- implicit val pos: Position = param.pos
+ implicit val pos = param.pos
js.ParamDef(encodeLocalSym(param), toIRType(param.info),
mutable = false, rest = false)
}
@@ -621,7 +621,7 @@ class JSCodeGen()(implicit ctx: Context) {
/* Any JavaScript expression is also a statement, but at least we get rid
* of some pure expressions that come from our own codegen.
*/
- implicit val pos: Position = tree.pos
+ implicit val pos = tree.pos
tree match {
case js.Block(stats :+ expr) => js.Block(stats :+ exprToStat(expr))
case _:js.Literal | js.This() => js.Skip()
@@ -644,7 +644,7 @@ class JSCodeGen()(implicit ctx: Context) {
* is transformed into an equivalent portion of the JS AST.
*/
private def genStatOrExpr(tree: Tree, isStat: Boolean): js.Tree = {
- implicit val pos: Position = tree.pos
+ implicit val pos = tree.pos
ctx.debuglog(" " + tree)
ctx.debuglog("")
@@ -902,7 +902,7 @@ class JSCodeGen()(implicit ctx: Context) {
* primitives, JS calls, etc. They are further dispatched in here.
*/
private def genApply(tree: Apply, isStat: Boolean): js.Tree = {
- implicit val pos: Position = tree.pos
+ implicit val pos = tree.pos
val args = tree.args
val sym = tree.fun.symbol
@@ -951,7 +951,7 @@ class JSCodeGen()(implicit ctx: Context) {
* irrelevant.
*/
private def genSuperCall(tree: Apply, isStat: Boolean): js.Tree = {
- implicit val pos: Position = tree.pos
+ implicit val pos = tree.pos
val Apply(fun @ Select(sup @ Super(_, mix), _), args) = tree
val sym = fun.symbol
@@ -987,7 +987,7 @@ class JSCodeGen()(implicit ctx: Context) {
* * regular new
*/
private def genApplyNew(tree: Apply): js.Tree = {
- implicit val pos: Position = tree.pos
+ implicit val pos = tree.pos
val Apply(fun @ Select(New(tpt), nme.CONSTRUCTOR), args) = tree
val ctor = fun.symbol
@@ -1023,7 +1023,7 @@ class JSCodeGen()(implicit ctx: Context) {
private def genPrimitiveOp(tree: Apply, isStat: Boolean): js.Tree = {
import scala.tools.nsc.backend.ScalaPrimitives._
- implicit val pos: Position = tree.pos
+ implicit val pos = tree.pos
val Apply(fun, args) = tree
val receiver = qualifierOf(fun)
@@ -1063,7 +1063,7 @@ class JSCodeGen()(implicit ctx: Context) {
private def genSimpleUnaryOp(tree: Apply, arg: Tree, code: Int): js.Tree = {
import scala.tools.nsc.backend.ScalaPrimitives._
- implicit val pos: Position = tree.pos
+ implicit val pos = tree.pos
val genArg = genExpr(arg)
val resultIRType = toIRType(tree.tpe)
@@ -1118,7 +1118,7 @@ class JSCodeGen()(implicit ctx: Context) {
}
import OpTypes._
- implicit val pos: Position = tree.pos
+ implicit val pos = tree.pos
val lhsIRType = toIRType(lhs.tpe)
val rhsIRType = toIRType(rhs.tpe)
@@ -1374,7 +1374,7 @@ class JSCodeGen()(implicit ctx: Context) {
*/
private def genStringConcat(tree: Apply, receiver: Tree,
args: List[Tree]): js.Tree = {
- implicit val pos: Position = tree.pos
+ implicit val pos = tree.pos
val arg = args.head
@@ -1401,7 +1401,7 @@ class JSCodeGen()(implicit ctx: Context) {
/** Gen JS code for a call to Any.## */
private def genScalaHash(tree: Apply, receiver: Tree): js.Tree = {
- implicit val pos: Position = tree.pos
+ implicit val pos = tree.pos
genModuleApplyMethod(defn.ScalaRuntimeModule.requiredMethod(nme.hash_),
List(genExpr(receiver)))
@@ -1411,7 +1411,7 @@ class JSCodeGen()(implicit ctx: Context) {
private def genArrayOp(tree: Tree, code: Int): js.Tree = {
import scala.tools.nsc.backend.ScalaPrimitives._
- implicit val pos: Position = tree.pos
+ implicit val pos = tree.pos
val Apply(fun, args) = tree
val arrayObj = qualifierOf(fun)
@@ -1462,7 +1462,7 @@ class JSCodeGen()(implicit ctx: Context) {
// common case for which there is no side-effect nor NPE
genArg
case _ =>
- implicit val pos: Position = tree.pos
+ implicit val pos = tree.pos
/* TODO Check for a null receiver?
* In theory, it's UB, but that decision should be left for link time.
*/
@@ -1474,7 +1474,7 @@ class JSCodeGen()(implicit ctx: Context) {
private def genCoercion(tree: Apply, receiver: Tree, code: Int): js.Tree = {
import scala.tools.nsc.backend.ScalaPrimitives._
- implicit val pos: Position = tree.pos
+ implicit val pos = tree.pos
val source = genExpr(receiver)
@@ -1544,7 +1544,7 @@ class JSCodeGen()(implicit ctx: Context) {
/** Gen a call to the special `throw` method. */
private def genThrow(tree: Apply, args: List[Tree]): js.Tree = {
- implicit val pos: Position = tree.pos
+ implicit val pos = tree.pos
val exception = args.head
val genException = genExpr(exception)
js.Throw {
@@ -1568,7 +1568,7 @@ class JSCodeGen()(implicit ctx: Context) {
* * Regular method call
*/
private def genNormalApply(tree: Apply, isStat: Boolean): js.Tree = {
- implicit val pos: Position = tree.pos
+ implicit val pos = tree.pos
val fun = tree.fun match {
case fun: Ident => desugarIdent(fun).get
@@ -1616,7 +1616,7 @@ class JSCodeGen()(implicit ctx: Context) {
superIn: Option[Symbol] = None)(
implicit pos: Position): js.Tree = {
- implicit val pos: Position = tree.pos
+ implicit val pos = tree.pos
def noSpread = !args.exists(_.isInstanceOf[js.JSSpread])
val argc = args.size // meaningful only for methods that don't have varargs
@@ -1775,7 +1775,7 @@ class JSCodeGen()(implicit ctx: Context) {
* primitive instead.)
*/
private def genTypeApply(tree: TypeApply): js.Tree = {
- implicit val pos: Position = tree.pos
+ implicit val pos = tree.pos
val TypeApply(fun, targs) = tree
@@ -1803,7 +1803,7 @@ class JSCodeGen()(implicit ctx: Context) {
/** Gen JS code for a Java Seq literal. */
private def genJavaSeqLiteral(tree: JavaSeqLiteral): js.Tree = {
- implicit val pos: Position = tree.pos
+ implicit val pos = tree.pos
val genElems = tree.elems.map(genExpr)
val arrayType = toReferenceType(tree.tpe).asInstanceOf[jstpe.ArrayType]
@@ -1852,7 +1852,7 @@ class JSCodeGen()(implicit ctx: Context) {
* available in the `body`.
*/
private def genClosure(tree: Closure): js.Tree = {
- implicit val pos: Position = tree.pos
+ implicit val pos = tree.pos
val Closure(env, call, functionalInterface) = tree
val envSize = env.size
@@ -1868,7 +1868,7 @@ class JSCodeGen()(implicit ctx: Context) {
val allCaptureValues = qualifier :: env
val (formalCaptures, actualCaptures) = allCaptureValues.map { value =>
- implicit val pos: Position = value.pos
+ implicit val pos = value.pos
val formalIdent = value match {
case Ident(name) => freshLocalIdent(name.toString)
case This(_) => freshLocalIdent("this")
@@ -1988,7 +1988,7 @@ class JSCodeGen()(implicit ctx: Context) {
/** Gen JS code for an isInstanceOf test (for reference types only) */
private def genIsInstanceOf(tree: Tree, value: js.Tree, to: Type): js.Tree = {
- implicit val pos: Position = tree.pos
+ implicit val pos = tree.pos
val sym = to.widenDealias.typeSymbol
if (sym == defn.ObjectClass) {
@@ -2242,7 +2242,7 @@ class JSCodeGen()(implicit ctx: Context) {
* to perform the conversion to js.Array, then wrap in a Spread
* operator.
*/
- implicit val pos: Position = arg.pos
+ implicit val pos = arg.pos
val jsArrayArg = genModuleApplyMethod(
jsdefn.RuntimePackage_genTraversableOnce2jsArray,
List(genExpr(arg)))
@@ -2259,7 +2259,7 @@ class JSCodeGen()(implicit ctx: Context) {
*/
private def tryGenRepeatedParamAsJSArray(arg: Tree,
handleNil: Boolean): Option[List[js.Tree]] = {
- implicit val pos: Position = arg.pos
+ implicit val pos = arg.pos
// Given a method `def foo(args: T*)`
arg match {
diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala
index a7c449947..51fa15706 100644
--- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala
+++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala
@@ -39,6 +39,10 @@ import dotty.tools.dotc.core.Names.TypeName
import scala.annotation.tailrec
class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Map[Symbol, Set[ClassSymbol]])(implicit ctx: Context) extends BackendInterface{
+ import Symbols.{toDenot, toClassDenot}
+ // Dotty deviation: Need to (re-)import implicit decorators here because otherwise
+ // they would be shadowed by the more deeply nested `symHelper` decorator.
+
type Symbol = Symbols.Symbol
type Type = Types.Type
type Tree = tpd.Tree
@@ -140,7 +144,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma
val externalEqualsNumChar: Symbol = NoSymbol // ctx.requiredMethod(BoxesRunTimeTypeRef, nme.equalsNumChar) // this method is private
val externalEqualsNumObject: Symbol = defn.BoxesRunTimeModule.requiredMethod(nme.equalsNumObject)
val externalEquals: Symbol = defn.BoxesRunTimeClass.info.decl(nme.equals_).suchThat(toDenot(_).info.firstParamTypes.size == 2).symbol
- val MaxFunctionArity: Int = Definitions.MaxFunctionArity
+ val MaxFunctionArity: Int = Definitions.MaxImplementedFunctionArity
val FunctionClass: Array[Symbol] = defn.FunctionClassPerRun()
val AbstractFunctionClass: Array[Symbol] = defn.AbstractFunctionClassPerRun()
val PartialFunctionClass: Symbol = defn.PartialFunctionClass
@@ -206,18 +210,15 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma
implicit val ConstantClassTag: ClassTag[Constant] = ClassTag[Constant](classOf[Constant])
implicit val ClosureTag: ClassTag[Closure] = ClassTag[Closure](classOf[Closure])
- /* dont emit any annotations for now*/
- def isRuntimeVisible(annot: Annotation): Boolean = {
- annot.atp.typeSymbol.getAnnotation(AnnotationRetentionAttr) match {
- case Some(retentionAnnot) =>
- retentionAnnot.tree.find(_.symbol == AnnotationRetentionRuntimeAttr).isDefined
- case _ =>
- // SI-8926: if the annotation class symbol doesn't have a @RetentionPolicy annotation, the
- // annotation is emitted with visibility `RUNTIME`
- // dotty bug: #389
- true
+ def isRuntimeVisible(annot: Annotation): Boolean =
+ if (toDenot(annot.atp.typeSymbol).hasAnnotation(AnnotationRetentionAttr))
+ retentionPolicyOf(annot) == AnnotationRetentionRuntimeAttr
+ else {
+ // SI-8926: if the annotation class symbol doesn't have a @RetentionPolicy annotation, the
+ // annotation is emitted with visibility `RUNTIME`
+ // dotty bug: #389
+ true
}
- }
def shouldEmitAnnotation(annot: Annotation): Boolean = {
annot.symbol.isJavaDefined &&
@@ -227,7 +228,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma
private def retentionPolicyOf(annot: Annotation): Symbol =
annot.atp.typeSymbol.getAnnotation(AnnotationRetentionAttr).
- flatMap(_.argument(0).map(_.symbol)).getOrElse(AnnotationRetentionClassAttr)
+ flatMap(_.argumentConstant(0).map(_.symbolValue)).getOrElse(AnnotationRetentionClassAttr)
private def emitArgument(av: AnnotationVisitor,
name: String,
@@ -559,7 +560,10 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma
def javaBinaryName: Name = toDenot(sym).fullNameSeparated("/") // addModuleSuffix(fullNameInternal('/'))
def javaClassName: String = toDenot(sym).fullName.toString// addModuleSuffix(fullNameInternal('.')).toString
def name: Name = sym.name
- def rawname: Name = sym.name // todo ????
+ def rawname: Name = {
+ val original = toDenot(sym).initial
+ sym.name(ctx.withPhase(original.validFor.phaseId))
+ }
// types
def info: Type = toDenot(sym).info
@@ -686,8 +690,6 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma
else sym.enclosingClass(ctx.withPhase(ctx.flattenPhase.prev))
} //todo is handled specially for JavaDefined symbols in scalac
-
-
// members
def primaryConstructor: Symbol = toDenot(sym).primaryConstructor
@@ -708,7 +710,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma
}
else Nil
- def annotations: List[Annotation] = Nil
+ def annotations: List[Annotation] = toDenot(sym).annotations
def companionModuleMembers: List[Symbol] = {
// phase travel to exitingPickler: this makes sure that memberClassesOf only sees member classes,
// not local classes of the companion module (E in the exmaple) that were lifted by lambdalift.
@@ -1027,7 +1029,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma
case JavaArrayType(elem) => elem
case _ =>
ctx.error(s"JavaSeqArray with type ${field.tpe} reached backend: $field", field.pos)
- ErrorType
+ UnspecifiedErrorType
}
def _2: List[Tree] = field.elems
}
diff --git a/compiler/src/dotty/tools/backend/jvm/scalaPrimitives.scala b/compiler/src/dotty/tools/backend/jvm/scalaPrimitives.scala
index 0027defa7..89831e56b 100644
--- a/compiler/src/dotty/tools/backend/jvm/scalaPrimitives.scala
+++ b/compiler/src/dotty/tools/backend/jvm/scalaPrimitives.scala
@@ -12,7 +12,7 @@ import dotty.tools.dotc.ast.tpd._
import dotty.tools.dotc.core.Names.TermName
import dotty.tools.dotc.core.StdNames
import dotty.tools.dotc.core.StdNames._
-import dotty.tools.dotc.core.Types.{JavaArrayType, ErrorType, Type}
+import dotty.tools.dotc.core.Types.{JavaArrayType, UnspecifiedErrorType, Type}
import scala.collection.{ mutable, immutable }
@@ -73,7 +73,7 @@ class DottyPrimitives(ctx: Context) {
case JavaArrayType(el) => el
case _ =>
ctx.error(s"expected Array $tpe")
- ErrorType
+ UnspecifiedErrorType
}
code match {
@@ -125,7 +125,7 @@ class DottyPrimitives(ctx: Context) {
/** Initialize the primitive map */
private def init: immutable.Map[Symbol, Int] = {
- implicit val ctx: Context = this.ctx
+ implicit val ctx = this.ctx
import core.Symbols.defn
val primitives = new mutable.HashMap[Symbol, Int]()
diff --git a/compiler/src/dotty/tools/dotc/Compiler.scala b/compiler/src/dotty/tools/dotc/Compiler.scala
index ad3249be2..900d2b0e3 100644
--- a/compiler/src/dotty/tools/dotc/Compiler.scala
+++ b/compiler/src/dotty/tools/dotc/Compiler.scala
@@ -61,6 +61,7 @@ class Compiler {
new PatternMatcher, // Compile pattern matches
new ExplicitOuter, // Add accessors to outer classes from nested ones.
new ExplicitSelf, // Make references to non-trivial self types explicit as casts
+ new ShortcutImplicits, // Allow implicit functions without creating closures
new CrossCastAnd, // Normalize selections involving intersection types.
new Splitter), // Expand selections involving union types into conditionals
List(new VCInlineMethods, // Inlines calls to value class methods
diff --git a/compiler/src/dotty/tools/dotc/ast/Desugar.scala b/compiler/src/dotty/tools/dotc/ast/Desugar.scala
index 4b2ff1bc3..211683c0a 100644
--- a/compiler/src/dotty/tools/dotc/ast/Desugar.scala
+++ b/compiler/src/dotty/tools/dotc/ast/Desugar.scala
@@ -7,6 +7,7 @@ import util.Positions._, Types._, Contexts._, Constants._, Names._, NameOps._, F
import SymDenotations._, Symbols._, StdNames._, Annotations._, Trees._
import Decorators._
import language.higherKinds
+import typer.FrontEnd
import collection.mutable.ListBuffer
import util.Property
import reporting.diagnostic.messages._
@@ -24,7 +25,6 @@ object desugar {
/** Names of methods that are added unconditionally to case classes */
def isDesugaredCaseClassMethodName(name: Name)(implicit ctx: Context): Boolean =
- name == nme.isDefined ||
name == nme.copy ||
name == nme.productArity ||
name.isSelectorName
@@ -124,6 +124,13 @@ object desugar {
else vdef
}
+ def makeImplicitParameters(tpts: List[Tree], forPrimaryConstructor: Boolean)(implicit ctx: Context) =
+ for (tpt <- tpts) yield {
+ val paramFlags: FlagSet = if (forPrimaryConstructor) PrivateLocalParamAccessor else Param
+ val epname = ctx.freshName(nme.EVIDENCE_PARAM_PREFIX).toTermName
+ ValDef(epname, tpt, EmptyTree).withFlags(paramFlags | Implicit)
+ }
+
/** Expand context bounds to evidence params. E.g.,
*
* def f[T >: L <: H : B](params)
@@ -142,16 +149,17 @@ object desugar {
val DefDef(name, tparams, vparamss, tpt, rhs) = meth
val mods = meth.mods
val epbuf = new ListBuffer[ValDef]
- val tparams1 = tparams mapConserve {
- case tparam @ TypeDef(_, ContextBounds(tbounds, cxbounds)) =>
- for (cxbound <- cxbounds) {
- val paramFlags: FlagSet = if (isPrimaryConstructor) PrivateLocalParamAccessor else Param
- val epname = ctx.freshName(nme.EVIDENCE_PARAM_PREFIX).toTermName
- epbuf += ValDef(epname, cxbound, EmptyTree).withFlags(paramFlags | Implicit)
- }
- cpy.TypeDef(tparam)(rhs = tbounds)
- case tparam =>
- tparam
+ def desugarContextBounds(rhs: Tree): Tree = rhs match {
+ case ContextBounds(tbounds, cxbounds) =>
+ epbuf ++= makeImplicitParameters(cxbounds, isPrimaryConstructor)
+ tbounds
+ case PolyTypeTree(tparams, body) =>
+ cpy.PolyTypeTree(rhs)(tparams, desugarContextBounds(body))
+ case _ =>
+ rhs
+ }
+ val tparams1 = tparams mapConserve { tparam =>
+ cpy.TypeDef(tparam)(rhs = desugarContextBounds(tparam.rhs))
}
val meth1 = addEvidenceParams(cpy.DefDef(meth)(tparams = tparams1), epbuf.toList)
@@ -338,10 +346,10 @@ object desugar {
if (isCaseClass) {
def syntheticProperty(name: TermName, rhs: Tree) =
DefDef(name, Nil, Nil, TypeTree(), rhs).withMods(synthetic)
- val isDefinedMeth = syntheticProperty(nme.isDefined, Literal(Constant(true)))
val caseParams = constrVparamss.head.toArray
- val productElemMeths = for (i <- 0 until arity) yield
- syntheticProperty(nme.selectorName(i), Select(This(EmptyTypeIdent), caseParams(i).name))
+ val productElemMeths =
+ for (i <- 0 until arity if nme.selectorName(i) `ne` caseParams(i).name)
+ yield syntheticProperty(nme.selectorName(i), Select(This(EmptyTypeIdent), caseParams(i).name))
def isRepeated(tree: Tree): Boolean = tree match {
case PostfixOp(_, nme.raw.STAR) => true
case ByNameTypeTree(tree1) => isRepeated(tree1)
@@ -356,7 +364,7 @@ object desugar {
if (mods.is(Abstract) || hasRepeatedParam) Nil // cannot have default arguments for repeated parameters, hence copy method is not issued
else {
def copyDefault(vparam: ValDef) =
- makeAnnotated(defn.UncheckedVarianceAnnot, refOfDef(vparam))
+ makeAnnotated("scala.annotation.unchecked.uncheckedVariance", refOfDef(vparam))
val copyFirstParams = derivedVparamss.head.map(vparam =>
cpy.ValDef(vparam)(rhs = copyDefault(vparam)))
val copyRestParamss = derivedVparamss.tail.nestedMap(vparam =>
@@ -364,7 +372,7 @@ object desugar {
DefDef(nme.copy, derivedTparams, copyFirstParams :: copyRestParamss, TypeTree(), creatorExpr)
.withMods(synthetic) :: Nil
}
- copyMeths ::: isDefinedMeth :: productElemMeths.toList
+ copyMeths ::: productElemMeths.toList
}
else Nil
@@ -552,7 +560,7 @@ object desugar {
case VarPattern(named, tpt) =>
derivedValDef(original, named, tpt, rhs, mods)
case _ =>
- val rhsUnchecked = makeAnnotated(defn.UncheckedAnnot, rhs)
+ val rhsUnchecked = makeAnnotated("scala.unchecked", rhs)
val vars = getVariables(pat)
val isMatchingTuple: Tree => Boolean = {
case Tuple(es) => es.length == vars.length
@@ -676,11 +684,33 @@ object desugar {
Function(param :: Nil, Block(vdefs, body))
}
- /** Add annotation with class `cls` to tree:
- * tree @cls
+ def makeImplicitFunction(formals: List[Type], body: Tree)(implicit ctx: Context): Tree = {
+ val params = makeImplicitParameters(formals.map(TypeTree), forPrimaryConstructor = false)
+ new ImplicitFunction(params, body)
+ }
+
+ /** Add annotation to tree:
+ * tree @fullName
+ *
+ * The annotation is usually represented as a TypeTree referring to the class
+ * with the given name `fullName`. However, if the annotation matches a file name
+ * that is still to be entered, the annotation is represented as a cascade of `Selects`
+ * following `fullName`. This is necessary so that we avoid reading an annotation from
+ * the classpath that is also compiled from source.
*/
- def makeAnnotated(cls: Symbol, tree: Tree)(implicit ctx: Context) =
- Annotated(tree, untpd.New(untpd.TypeTree(cls.typeRef), Nil))
+ def makeAnnotated(fullName: String, tree: Tree)(implicit ctx: Context) = {
+ val parts = fullName.split('.')
+ val ttree = ctx.typerPhase match {
+ case phase: FrontEnd if phase.stillToBeEntered(parts.last) =>
+ val prefix =
+ ((Ident(nme.ROOTPKG): Tree) /: parts.init)((qual, name) =>
+ Select(qual, name.toTermName))
+ Select(prefix, parts.last.toTypeName)
+ case _ =>
+ TypeTree(ctx.requiredClass(fullName).typeRef)
+ }
+ Annotated(tree, untpd.New(ttree, Nil))
+ }
private def derivedValDef(original: Tree, named: NameTree, tpt: Tree, rhs: Tree, mods: Modifiers)(implicit ctx: Context) = {
val vdef = ValDef(named.name.asTermName, tpt, rhs)
@@ -916,7 +946,11 @@ object desugar {
val elems = segments flatMap {
case ts: Thicket => ts.trees.tail
case t => Nil
+ } map {
+ case Block(Nil, expr) => expr // important for interpolated string as patterns, see i1773.scala
+ case t => t
}
+
Apply(Select(Apply(Ident(nme.StringContext), strs), id), elems)
case InfixOp(l, op, r) =>
if (ctx.mode is Mode.Type)
@@ -1079,6 +1113,10 @@ object desugar {
collect(tree)
case Tuple(trees) =>
trees foreach collect
+ case Thicket(trees) =>
+ trees foreach collect
+ case Block(Nil, expr) =>
+ collect(expr)
case _ =>
}
collect(tree)
diff --git a/compiler/src/dotty/tools/dotc/ast/TreeInfo.scala b/compiler/src/dotty/tools/dotc/ast/TreeInfo.scala
index d1e6bd38a..da83d0644 100644
--- a/compiler/src/dotty/tools/dotc/ast/TreeInfo.scala
+++ b/compiler/src/dotty/tools/dotc/ast/TreeInfo.scala
@@ -290,6 +290,16 @@ trait UntypedTreeInfo extends TreeInfo[Untyped] { self: Trees.Instance[Untyped]
case _ => false
}
+ /** Is `tree` an implicit function or closure, possibly nested in a block? */
+ def isImplicitClosure(tree: Tree)(implicit ctx: Context): Boolean = unsplice(tree) match {
+ case Function((param: untpd.ValDef) :: _, _) => param.mods.is(Implicit)
+ case Closure(_, meth, _) => true
+ case Block(Nil, expr) => isImplicitClosure(expr)
+ case Block(DefDef(nme.ANON_FUN, _, (param :: _) :: _, _, _) :: Nil, _: Closure) =>
+ param.mods.is(Implicit)
+ case _ => false
+ }
+
// todo: fill with other methods from TreeInfo that only apply to untpd.Tree's
}
@@ -501,7 +511,7 @@ trait TypedTreeInfo extends TreeInfo[Type] { self: Trees.Instance[Type] =>
*/
object closure {
def unapply(tree: Tree): Option[(List[Tree], Tree, Tree)] = tree match {
- case Block(_, Closure(env, meth, tpt)) => Some(env, meth, tpt)
+ case Block(_, expr) => unapply(expr)
case Closure(env, meth, tpt) => Some(env, meth, tpt)
case _ => None
}
diff --git a/compiler/src/dotty/tools/dotc/ast/Trees.scala b/compiler/src/dotty/tools/dotc/ast/Trees.scala
index 2801bcae2..798f0f567 100644
--- a/compiler/src/dotty/tools/dotc/ast/Trees.scala
+++ b/compiler/src/dotty/tools/dotc/ast/Trees.scala
@@ -32,7 +32,7 @@ object Trees {
/** Property key for trees with documentation strings attached */
val DocComment = new Property.Key[Comment]
- @sharable private var nextId = 0 // for debugging
+ @sharable private var nextId = 0 // for debugging
type LazyTree = AnyRef /* really: Tree | Lazy[Tree] */
type LazyTreeList = AnyRef /* really: List[Tree] | Lazy[List[Tree]] */
@@ -113,7 +113,7 @@ object Trees {
* type. (Overridden by empty trees)
*/
def withType(tpe: Type)(implicit ctx: Context): ThisTree[Type] = {
- if (tpe == ErrorType) assert(ctx.reporter.errorsReported)
+ if (tpe.isInstanceOf[ErrorType]) assert(ctx.reporter.errorsReported)
withTypeUnchecked(tpe)
}
@@ -890,6 +890,11 @@ object Trees {
case tree: Select if (qualifier eq tree.qualifier) && (name == tree.name) => tree
case _ => finalize(tree, untpd.Select(qualifier, name))
}
+ /** Copy Ident or Select trees */
+ def Ref(tree: RefTree)(name: Name)(implicit ctx: Context) = tree match {
+ case Ident(_) => Ident(tree)(name)
+ case Select(qual, _) => Select(tree)(qual, name)
+ }
def This(tree: Tree)(qual: untpd.Ident): This = tree match {
case tree: This if qual eq tree.qual => tree
case _ => finalize(tree, untpd.This(qual))
@@ -1224,7 +1229,7 @@ object Trees {
case AppliedTypeTree(tpt, args) =>
this(this(x, tpt), args)
case PolyTypeTree(tparams, body) =>
- implicit val ctx: Context = localCtx
+ implicit val ctx = localCtx
this(this(x, tparams), body)
case ByNameTypeTree(result) =>
this(x, result)
@@ -1237,13 +1242,13 @@ object Trees {
case UnApply(fun, implicits, patterns) =>
this(this(this(x, fun), implicits), patterns)
case tree @ ValDef(name, tpt, _) =>
- implicit val ctx: Context = localCtx
+ implicit val ctx = localCtx
this(this(x, tpt), tree.rhs)
case tree @ DefDef(name, tparams, vparamss, tpt, _) =>
- implicit val ctx: Context = localCtx
+ implicit val ctx = localCtx
this(this((this(x, tparams) /: vparamss)(apply), tpt), tree.rhs)
case TypeDef(name, rhs) =>
- implicit val ctx: Context = localCtx
+ implicit val ctx = localCtx
this(x, rhs)
case tree @ Template(constr, parents, self, _) =>
this(this(this(this(x, constr), parents), self), tree.body)
diff --git a/compiler/src/dotty/tools/dotc/ast/tpd.scala b/compiler/src/dotty/tools/dotc/ast/tpd.scala
index cd6b3fcf2..433808e8e 100644
--- a/compiler/src/dotty/tools/dotc/ast/tpd.scala
+++ b/compiler/src/dotty/tools/dotc/ast/tpd.scala
@@ -450,7 +450,8 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
} else foldOver(sym, tree)
}
- override val cpy = new TypedTreeCopier
+ override val cpy: TypedTreeCopier = // Type ascription needed to pick up any new members in TreeCopier (currently there are none)
+ new TypedTreeCopier
class TypedTreeCopier extends TreeCopier {
def postProcess(tree: Tree, copied: untpd.Tree): copied.ThisTree[Type] =
diff --git a/compiler/src/dotty/tools/dotc/ast/untpd.scala b/compiler/src/dotty/tools/dotc/ast/untpd.scala
index 6c5210287..f3ffce8f8 100644
--- a/compiler/src/dotty/tools/dotc/ast/untpd.scala
+++ b/compiler/src/dotty/tools/dotc/ast/untpd.scala
@@ -53,6 +53,12 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
override def isTerm = body.isTerm
override def isType = body.isType
}
+
+ /** An implicit function type */
+ class ImplicitFunction(args: List[Tree], body: Tree) extends Function(args, body) {
+ override def toString = s"ImplicitFunction($args, $body)"
+ }
+
/** A function created from a wildcard expression
* @param placeHolderParams a list of definitions of synthetic parameters
* @param body the function body where wildcards are replaced by
@@ -111,7 +117,7 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
case class Var() extends Mod(Flags.Mutable)
- case class Implicit(flag: FlagSet = Flags.ImplicitCommon) extends Mod(flag)
+ case class Implicit() extends Mod(Flags.ImplicitCommon)
case class Final() extends Mod(Flags.Final)
@@ -270,8 +276,6 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
// ------ Additional creation methods for untyped only -----------------
- // def TypeTree(tpe: Type): TypeTree = TypeTree().withType(tpe) todo: move to untpd/tpd
-
/** new pre.C[Ts](args1)...(args_n)
* ==>
* (new pre.C).<init>[Ts](args1)...(args_n)
diff --git a/compiler/src/dotty/tools/dotc/config/Config.scala b/compiler/src/dotty/tools/dotc/config/Config.scala
index 7744a5479..119af9483 100644
--- a/compiler/src/dotty/tools/dotc/config/Config.scala
+++ b/compiler/src/dotty/tools/dotc/config/Config.scala
@@ -133,6 +133,8 @@ object Config {
*/
final val LogPendingFindMemberThreshold = 10
- /** Maximal number of outstanding recursive calls to findMember */
+ /** Maximal number of outstanding recursive calls to findMember before backing out
+ * when findMemberLimit is set.
+ */
final val PendingFindMemberLimit = LogPendingFindMemberThreshold * 4
}
diff --git a/compiler/src/dotty/tools/dotc/config/JavaPlatform.scala b/compiler/src/dotty/tools/dotc/config/JavaPlatform.scala
index a695202d3..b5bfbb39f 100644
--- a/compiler/src/dotty/tools/dotc/config/JavaPlatform.scala
+++ b/compiler/src/dotty/tools/dotc/config/JavaPlatform.scala
@@ -18,6 +18,7 @@ class JavaPlatform extends Platform {
currentClassPath = Some(new PathResolver().result)
val cp = currentClassPath.get
//println(cp)
+ //println("------------------")
cp
}
diff --git a/compiler/src/dotty/tools/dotc/config/PathResolver.scala b/compiler/src/dotty/tools/dotc/config/PathResolver.scala
index aa4d8aeb0..8df9a8c0e 100644
--- a/compiler/src/dotty/tools/dotc/config/PathResolver.scala
+++ b/compiler/src/dotty/tools/dotc/config/PathResolver.scala
@@ -143,7 +143,7 @@ object PathResolver {
println(Defaults)
}
else {
- implicit val ctx: Context = (new ContextBase).initialCtx // Dotty deviation: implicits need explicit type
+ implicit val ctx = (new ContextBase).initialCtx
val ArgsSummary(sstate, rest, errors) =
ctx.settings.processArguments(args.toList, true)
errors.foreach(println)
diff --git a/compiler/src/dotty/tools/dotc/config/ScalaSettings.scala b/compiler/src/dotty/tools/dotc/config/ScalaSettings.scala
index fd2ded0b5..21a6c1165 100644
--- a/compiler/src/dotty/tools/dotc/config/ScalaSettings.scala
+++ b/compiler/src/dotty/tools/dotc/config/ScalaSettings.scala
@@ -69,7 +69,7 @@ class ScalaSettings extends Settings.SettingGroup {
val genPhaseGraph = StringSetting("-Xgenerate-phase-graph", "file", "Generate the phase graphs (outputs .dot files) to fileX.dot.", "")
val XlogImplicits = BooleanSetting("-Xlog-implicits", "Show more detail on why some implicits are not applicable.")
val XminImplicitSearchDepth = IntSetting("-Xmin-implicit-search-depth", "Set number of levels of implicit searches undertaken before checking for divergence.", 5)
- val xmaxInlines = IntSetting("-Xmax-inlines", "Maximal number of successive inlines", 70)
+ val xmaxInlines = IntSetting("-Xmax-inlines", "Maximal number of successive inlines", 32)
val logImplicitConv = BooleanSetting("-Xlog-implicit-conversions", "Print a message whenever an implicit conversion is inserted.")
val logReflectiveCalls = BooleanSetting("-Xlog-reflective-calls", "Print a message when a reflective method call is generated")
val logFreeTerms = BooleanSetting("-Xlog-free-terms", "Print a message when reification creates a free term.")
diff --git a/compiler/src/dotty/tools/dotc/core/Comments.scala b/compiler/src/dotty/tools/dotc/core/Comments.scala
index 1e623db4d..2559209c3 100644
--- a/compiler/src/dotty/tools/dotc/core/Comments.scala
+++ b/compiler/src/dotty/tools/dotc/core/Comments.scala
@@ -119,7 +119,7 @@ object Comments {
def apply(comment: Comment, code: String, codePos: Position)(implicit ctx: Context) =
new UseCase(comment, code, codePos) {
val untpdCode = {
- val tree = new Parser(new SourceFile("<usecase>", code)).localDef(codePos.start, EmptyFlags)
+ val tree = new Parser(new SourceFile("<usecase>", code)).localDef(codePos.start)
tree match {
case tree: untpd.DefDef =>
diff --git a/compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala b/compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala
index 0e155b9e1..42df53fed 100644
--- a/compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala
+++ b/compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala
@@ -57,6 +57,7 @@ trait ConstraintHandling {
b match {
case b: AndOrType => occursIn(b.tp1) || occursIn(b.tp2)
case b: TypeVar => occursIn(b.origin)
+ case b: TermRef => occursIn(b.underlying)
case _ => false
}
}
diff --git a/compiler/src/dotty/tools/dotc/core/Contexts.scala b/compiler/src/dotty/tools/dotc/core/Contexts.scala
index 639c4d111..29629e505 100644
--- a/compiler/src/dotty/tools/dotc/core/Contexts.scala
+++ b/compiler/src/dotty/tools/dotc/core/Contexts.scala
@@ -216,8 +216,8 @@ object Contexts {
else if (isNonEmptyScopeContext) scope.implicitDecls
else Nil
val outerImplicits =
- if (isImportContext && importInfo.hiddenRoot.exists)
- outer.implicits exclude importInfo.hiddenRoot
+ if (isImportContext && importInfo.unimported.exists)
+ outer.implicits exclude importInfo.unimported
else
outer.implicits
if (implicitRefs.isEmpty) outerImplicits
@@ -262,6 +262,9 @@ object Contexts {
final def withPhaseNoLater(phase: Phase) =
if (phase.exists && ctx.phase.id > phase.id) withPhase(phase) else ctx
+ final def withPhaseNoEarlier(phase: Phase) =
+ if (phase.exists && ctx.phase.id < phase.id) withPhase(phase) else ctx
+
/** If -Ydebug is on, the top of the stack trace where this context
* was created, otherwise `null`.
*/
@@ -422,9 +425,18 @@ object Contexts {
final def withOwner(owner: Symbol): Context =
if (owner ne this.owner) fresh.setOwner(owner) else this
- override def toString =
+ final def withProperty[T](key: Key[T], value: Option[T]): Context =
+ if (property(key) == value) this
+ else value match {
+ case Some(v) => fresh.setProperty(key, v)
+ case None => fresh.dropProperty(key)
+ }
+
+ override def toString = {
+ def iinfo(implicit ctx: Context) = if (ctx.importInfo == null) "" else i"${ctx.importInfo.selectors}%, %"
"Context(\n" +
- (outersIterator map ( ctx => s" owner = ${ctx.owner}, scope = ${ctx.scope}") mkString "\n")
+ (outersIterator map ( ctx => s" owner = ${ctx.owner}, scope = ${ctx.scope}, import = ${iinfo(ctx)}") mkString "\n")
+ }
}
/** A condensed context provides only a small memory footprint over
@@ -468,6 +480,9 @@ object Contexts {
def setProperty[T](key: Key[T], value: T): this.type =
setMoreProperties(moreProperties.updated(key, value))
+ def dropProperty(key: Key[_]): this.type =
+ setMoreProperties(moreProperties - key)
+
def setPhase(pid: PhaseId): this.type = setPeriod(Period(runId, pid))
def setPhase(phase: Phase): this.type = setPeriod(Period(runId, phase.start, phase.end))
diff --git a/compiler/src/dotty/tools/dotc/core/Definitions.scala b/compiler/src/dotty/tools/dotc/core/Definitions.scala
index 4b090d9b1..45e37eb8b 100644
--- a/compiler/src/dotty/tools/dotc/core/Definitions.scala
+++ b/compiler/src/dotty/tools/dotc/core/Definitions.scala
@@ -12,13 +12,20 @@ import collection.mutable
import scala.reflect.api.{ Universe => ApiUniverse }
object Definitions {
- val MaxTupleArity, MaxAbstractFunctionArity = 22
- val MaxFunctionArity = 30
- // Awaiting a definite solution that drops the limit altogether, 30 gives a safety
- // margin over the previous 22, so that treecopiers in miniphases are allowed to
- // temporarily create larger closures. This is needed in lambda lift where large closures
- // are first formed by treecopiers before they are split apart into parameters and
- // environment in the lambdalift transform itself.
+
+ /** The maximum number of elements in a tuple or product.
+ * This should be removed once we go to hlists.
+ */
+ val MaxTupleArity = 22
+
+ /** The maximum arity N of a function type that's implemented
+ * as a trait `scala.FunctionN`. Functions of higher arity are possible,
+ * but are mapped in erasure to functions taking a single parameter of type
+ * Object[].
+ * The limit 22 is chosen for Scala2x interop. It could be something
+ * else without affecting the set of programs that can be compiled.
+ */
+ val MaxImplementedFunctionArity = 22
}
/** A class defining symbols and types of standard definitions
@@ -45,32 +52,29 @@ class Definitions {
ctx.newSymbol(owner, name, flags | Permanent, info)
private def newClassSymbol(owner: Symbol, name: TypeName, flags: FlagSet, infoFn: ClassSymbol => Type) =
- ctx.newClassSymbol(owner, name, flags | Permanent, infoFn).entered
+ ctx.newClassSymbol(owner, name, flags | Permanent, infoFn)
- private def newCompleteClassSymbol(owner: Symbol, name: TypeName, flags: FlagSet, parents: List[TypeRef], decls: Scope = newScope) =
+ private def enterCompleteClassSymbol(owner: Symbol, name: TypeName, flags: FlagSet, parents: List[TypeRef], decls: Scope = newScope) =
ctx.newCompleteClassSymbol(owner, name, flags | Permanent, parents, decls).entered
- private def newTopClassSymbol(name: TypeName, flags: FlagSet, parents: List[TypeRef]) =
- completeClass(newCompleteClassSymbol(ScalaPackageClass, name, flags, parents))
-
- private def newTypeField(cls: ClassSymbol, name: TypeName, flags: FlagSet, scope: MutableScope) =
+ private def enterTypeField(cls: ClassSymbol, name: TypeName, flags: FlagSet, scope: MutableScope) =
scope.enter(newSymbol(cls, name, flags, TypeBounds.empty))
- private def newTypeParam(cls: ClassSymbol, name: TypeName, flags: FlagSet, scope: MutableScope) =
- newTypeField(cls, name, flags | ClassTypeParamCreationFlags, scope)
+ private def enterTypeParam(cls: ClassSymbol, name: TypeName, flags: FlagSet, scope: MutableScope) =
+ enterTypeField(cls, name, flags | ClassTypeParamCreationFlags, scope)
- private def newSyntheticTypeParam(cls: ClassSymbol, scope: MutableScope, paramFlags: FlagSet, suffix: String = "T0") =
- newTypeParam(cls, suffix.toTypeName.expandedName(cls), ExpandedName | paramFlags, scope)
+ private def enterSyntheticTypeParam(cls: ClassSymbol, paramFlags: FlagSet, scope: MutableScope, suffix: String = "T0") =
+ enterTypeParam(cls, suffix.toTypeName.expandedName(cls), ExpandedName | paramFlags, scope)
// NOTE: Ideally we would write `parentConstrs: => Type*` but SIP-24 is only
// implemented in Dotty and not in Scala 2.
// See <http://docs.scala-lang.org/sips/pending/repeated-byname.html>.
- private def specialPolyClass(name: TypeName, paramFlags: FlagSet, parentConstrs: => Seq[Type]): ClassSymbol = {
+ private def enterSpecialPolyClass(name: TypeName, paramFlags: FlagSet, parentConstrs: => Seq[Type]): ClassSymbol = {
val completer = new LazyType {
def complete(denot: SymDenotation)(implicit ctx: Context): Unit = {
val cls = denot.asClass.classSymbol
val paramDecls = newScope
- val typeParam = newSyntheticTypeParam(cls, paramDecls, paramFlags)
+ val typeParam = enterSyntheticTypeParam(cls, paramFlags, paramDecls)
def instantiate(tpe: Type) =
if (tpe.typeParams.nonEmpty) tpe.appliedTo(typeParam.typeRef)
else tpe
@@ -79,31 +83,81 @@ class Definitions {
denot.info = ClassInfo(ScalaPackageClass.thisType, cls, parentRefs, paramDecls)
}
}
- newClassSymbol(ScalaPackageClass, name, EmptyFlags, completer)
+ newClassSymbol(ScalaPackageClass, name, EmptyFlags, completer).entered
+ }
+
+ /** The trait FunctionN or ImplicitFunctionN, for some N
+ * @param name The name of the trait to be created
+ *
+ * FunctionN traits follow this template:
+ *
+ * trait FunctionN[T0,...T{N-1}, R] extends Object {
+ * def apply($x0: T0, ..., $x{N_1}: T{N-1}): R
+ * }
+ *
+ * That is, they follow the template given for Function2..Function22 in the
+ * standard library, but without `tupled` and `curried` methods and without
+ * a `toString`.
+ *
+ * ImplicitFunctionN traits follow this template:
+ *
+ * trait ImplicitFunctionN[T0,...,T{N-1}, R] extends Object with FunctionN[T0,...,T{N-1}, R] {
+ * def apply(implicit $x0: T0, ..., $x{N_1}: T{N-1}): R
+ * }
+ */
+ private def newFunctionNTrait(name: TypeName) = {
+ val completer = new LazyType {
+ def complete(denot: SymDenotation)(implicit ctx: Context): Unit = {
+ val cls = denot.asClass.classSymbol
+ val decls = newScope
+ val arity = name.functionArity
+ val argParams =
+ for (i <- List.range(0, arity)) yield
+ enterTypeParam(cls, name ++ "$T" ++ i.toString, Contravariant, decls)
+ val resParam = enterTypeParam(cls, name ++ "$R", Covariant, decls)
+ val (methodType, parentTraits) =
+ if (name.startsWith(tpnme.ImplicitFunction)) {
+ val superTrait =
+ FunctionType(arity).appliedTo(argParams.map(_.typeRef) ::: resParam.typeRef :: Nil)
+ (ImplicitMethodType, ctx.normalizeToClassRefs(superTrait :: Nil, cls, decls))
+ }
+ else (MethodType, Nil)
+ val applyMeth =
+ decls.enter(
+ newMethod(cls, nme.apply,
+ methodType(argParams.map(_.typeRef), resParam.typeRef), Deferred))
+ denot.info =
+ ClassInfo(ScalaPackageClass.thisType, cls, ObjectType :: parentTraits, decls)
+ }
+ }
+ newClassSymbol(ScalaPackageClass, name, Trait, completer)
}
private def newMethod(cls: ClassSymbol, name: TermName, info: Type, flags: FlagSet = EmptyFlags): TermSymbol =
- newSymbol(cls, name.encode, flags | Method, info).entered.asTerm
+ newSymbol(cls, name.encode, flags | Method, info).asTerm
+
+ private def enterMethod(cls: ClassSymbol, name: TermName, info: Type, flags: FlagSet = EmptyFlags): TermSymbol =
+ newMethod(cls, name, info, flags).entered
- private def newAliasType(name: TypeName, tpe: Type, flags: FlagSet = EmptyFlags): TypeSymbol = {
+ private def enterAliasType(name: TypeName, tpe: Type, flags: FlagSet = EmptyFlags): TypeSymbol = {
val sym = newSymbol(ScalaPackageClass, name, flags, TypeAlias(tpe))
ScalaPackageClass.currentPackageDecls.enter(sym)
sym
}
- private def newPolyMethod(cls: ClassSymbol, name: TermName, typeParamCount: Int,
+ private def enterPolyMethod(cls: ClassSymbol, name: TermName, typeParamCount: Int,
resultTypeFn: PolyType => Type, flags: FlagSet = EmptyFlags) = {
val tparamNames = tpnme.syntheticTypeParamNames(typeParamCount)
val tparamBounds = tparamNames map (_ => TypeBounds.empty)
val ptype = PolyType(tparamNames)(_ => tparamBounds, resultTypeFn)
- newMethod(cls, name, ptype, flags)
+ enterMethod(cls, name, ptype, flags)
}
- private def newT1ParameterlessMethod(cls: ClassSymbol, name: TermName, resultTypeFn: PolyType => Type, flags: FlagSet) =
- newPolyMethod(cls, name, 1, resultTypeFn, flags)
+ private def enterT1ParameterlessMethod(cls: ClassSymbol, name: TermName, resultTypeFn: PolyType => Type, flags: FlagSet) =
+ enterPolyMethod(cls, name, 1, resultTypeFn, flags)
- private def newT1EmptyParamsMethod(cls: ClassSymbol, name: TermName, resultTypeFn: PolyType => Type, flags: FlagSet) =
- newPolyMethod(cls, name, 1, pt => MethodType(Nil, resultTypeFn(pt)), flags)
+ private def enterT1EmptyParamsMethod(cls: ClassSymbol, name: TermName, resultTypeFn: PolyType => Type, flags: FlagSet) =
+ enterPolyMethod(cls, name, 1, pt => MethodType(Nil, resultTypeFn(pt)), flags)
private def mkArityArray(name: String, arity: Int, countFrom: Int): Array[TypeRef] = {
val arr = new Array[TypeRef](arity + 1)
@@ -172,20 +226,20 @@ class Definitions {
* def getClass: java.lang.Class[T] = ???
* }
*/
- lazy val AnyClass: ClassSymbol = completeClass(newCompleteClassSymbol(ScalaPackageClass, tpnme.Any, Abstract, Nil))
+ lazy val AnyClass: ClassSymbol = completeClass(enterCompleteClassSymbol(ScalaPackageClass, tpnme.Any, Abstract, Nil))
def AnyType = AnyClass.typeRef
- lazy val AnyValClass: ClassSymbol = completeClass(newCompleteClassSymbol(ScalaPackageClass, tpnme.AnyVal, Abstract, List(AnyClass.typeRef)))
+ lazy val AnyValClass: ClassSymbol = completeClass(enterCompleteClassSymbol(ScalaPackageClass, tpnme.AnyVal, Abstract, List(AnyClass.typeRef)))
def AnyValType = AnyValClass.typeRef
- lazy val Any_== = newMethod(AnyClass, nme.EQ, methOfAny(BooleanType), Final)
- lazy val Any_!= = newMethod(AnyClass, nme.NE, methOfAny(BooleanType), Final)
- lazy val Any_equals = newMethod(AnyClass, nme.equals_, methOfAny(BooleanType))
- lazy val Any_hashCode = newMethod(AnyClass, nme.hashCode_, MethodType(Nil, IntType))
- lazy val Any_toString = newMethod(AnyClass, nme.toString_, MethodType(Nil, StringType))
- lazy val Any_## = newMethod(AnyClass, nme.HASHHASH, ExprType(IntType), Final)
- lazy val Any_getClass = newMethod(AnyClass, nme.getClass_, MethodType(Nil, ClassClass.typeRef.appliedTo(TypeBounds.empty)), Final)
- lazy val Any_isInstanceOf = newT1ParameterlessMethod(AnyClass, nme.isInstanceOf_, _ => BooleanType, Final)
- lazy val Any_asInstanceOf = newT1ParameterlessMethod(AnyClass, nme.asInstanceOf_, PolyParam(_, 0), Final)
+ lazy val Any_== = enterMethod(AnyClass, nme.EQ, methOfAny(BooleanType), Final)
+ lazy val Any_!= = enterMethod(AnyClass, nme.NE, methOfAny(BooleanType), Final)
+ lazy val Any_equals = enterMethod(AnyClass, nme.equals_, methOfAny(BooleanType))
+ lazy val Any_hashCode = enterMethod(AnyClass, nme.hashCode_, MethodType(Nil, IntType))
+ lazy val Any_toString = enterMethod(AnyClass, nme.toString_, MethodType(Nil, StringType))
+ lazy val Any_## = enterMethod(AnyClass, nme.HASHHASH, ExprType(IntType), Final)
+ lazy val Any_getClass = enterMethod(AnyClass, nme.getClass_, MethodType(Nil, ClassClass.typeRef.appliedTo(TypeBounds.empty)), Final)
+ lazy val Any_isInstanceOf = enterT1ParameterlessMethod(AnyClass, nme.isInstanceOf_, _ => BooleanType, Final)
+ lazy val Any_asInstanceOf = enterT1ParameterlessMethod(AnyClass, nme.asInstanceOf_, PolyParam(_, 0), Final)
def AnyMethods = List(Any_==, Any_!=, Any_equals, Any_hashCode,
Any_toString, Any_##, Any_getClass, Any_isInstanceOf, Any_asInstanceOf)
@@ -205,37 +259,37 @@ class Definitions {
}
def ObjectType = ObjectClass.typeRef
- lazy val AnyRefAlias: TypeSymbol = newAliasType(tpnme.AnyRef, ObjectType)
+ lazy val AnyRefAlias: TypeSymbol = enterAliasType(tpnme.AnyRef, ObjectType)
def AnyRefType = AnyRefAlias.typeRef
- lazy val Object_eq = newMethod(ObjectClass, nme.eq, methOfAnyRef(BooleanType), Final)
- lazy val Object_ne = newMethod(ObjectClass, nme.ne, methOfAnyRef(BooleanType), Final)
- lazy val Object_synchronized = newPolyMethod(ObjectClass, nme.synchronized_, 1,
+ lazy val Object_eq = enterMethod(ObjectClass, nme.eq, methOfAnyRef(BooleanType), Final)
+ lazy val Object_ne = enterMethod(ObjectClass, nme.ne, methOfAnyRef(BooleanType), Final)
+ lazy val Object_synchronized = enterPolyMethod(ObjectClass, nme.synchronized_, 1,
pt => MethodType(List(PolyParam(pt, 0)), PolyParam(pt, 0)), Final)
- lazy val Object_clone = newMethod(ObjectClass, nme.clone_, MethodType(Nil, ObjectType), Protected)
- lazy val Object_finalize = newMethod(ObjectClass, nme.finalize_, MethodType(Nil, UnitType), Protected)
- lazy val Object_notify = newMethod(ObjectClass, nme.notify_, MethodType(Nil, UnitType))
- lazy val Object_notifyAll = newMethod(ObjectClass, nme.notifyAll_, MethodType(Nil, UnitType))
- lazy val Object_wait = newMethod(ObjectClass, nme.wait_, MethodType(Nil, UnitType))
- lazy val Object_waitL = newMethod(ObjectClass, nme.wait_, MethodType(LongType :: Nil, UnitType))
- lazy val Object_waitLI = newMethod(ObjectClass, nme.wait_, MethodType(LongType :: IntType :: Nil, UnitType))
+ lazy val Object_clone = enterMethod(ObjectClass, nme.clone_, MethodType(Nil, ObjectType), Protected)
+ lazy val Object_finalize = enterMethod(ObjectClass, nme.finalize_, MethodType(Nil, UnitType), Protected)
+ lazy val Object_notify = enterMethod(ObjectClass, nme.notify_, MethodType(Nil, UnitType))
+ lazy val Object_notifyAll = enterMethod(ObjectClass, nme.notifyAll_, MethodType(Nil, UnitType))
+ lazy val Object_wait = enterMethod(ObjectClass, nme.wait_, MethodType(Nil, UnitType))
+ lazy val Object_waitL = enterMethod(ObjectClass, nme.wait_, MethodType(LongType :: Nil, UnitType))
+ lazy val Object_waitLI = enterMethod(ObjectClass, nme.wait_, MethodType(LongType :: IntType :: Nil, UnitType))
def ObjectMethods = List(Object_eq, Object_ne, Object_synchronized, Object_clone,
Object_finalize, Object_notify, Object_notifyAll, Object_wait, Object_waitL, Object_waitLI)
/** Dummy method needed by elimByName */
- lazy val dummyApply = newPolyMethod(
+ lazy val dummyApply = enterPolyMethod(
OpsPackageClass, nme.dummyApply, 1,
pt => MethodType(List(FunctionOf(Nil, PolyParam(pt, 0))), PolyParam(pt, 0)))
/** Method representing a throw */
- lazy val throwMethod = newMethod(OpsPackageClass, nme.THROWkw,
+ lazy val throwMethod = enterMethod(OpsPackageClass, nme.THROWkw,
MethodType(List(ThrowableType), NothingType))
- lazy val NothingClass: ClassSymbol = newCompleteClassSymbol(
+ lazy val NothingClass: ClassSymbol = enterCompleteClassSymbol(
ScalaPackageClass, tpnme.Nothing, AbstractFinal, List(AnyClass.typeRef))
def NothingType = NothingClass.typeRef
- lazy val NullClass: ClassSymbol = newCompleteClassSymbol(
+ lazy val NullClass: ClassSymbol = enterCompleteClassSymbol(
ScalaPackageClass, tpnme.Null, AbstractFinal, List(ObjectClass.typeRef))
def NullType = NullClass.typeRef
@@ -281,7 +335,7 @@ class Definitions {
lazy val SingletonClass: ClassSymbol =
// needed as a synthetic class because Scala 2.x refers to it in classfiles
// but does not define it as an explicit class.
- newCompleteClassSymbol(
+ enterCompleteClassSymbol(
ScalaPackageClass, tpnme.Singleton, PureInterfaceCreationFlags | Final,
List(AnyClass.typeRef), EmptyScope)
@@ -387,17 +441,17 @@ class Definitions {
lazy val BoxedDoubleModule = ctx.requiredModule("java.lang.Double")
lazy val BoxedUnitModule = ctx.requiredModule("java.lang.Void")
- lazy val ByNameParamClass2x = specialPolyClass(tpnme.BYNAME_PARAM_CLASS, Covariant, Seq(AnyType))
- lazy val EqualsPatternClass = specialPolyClass(tpnme.EQUALS_PATTERN, EmptyFlags, Seq(AnyType))
+ lazy val ByNameParamClass2x = enterSpecialPolyClass(tpnme.BYNAME_PARAM_CLASS, Covariant, Seq(AnyType))
+ lazy val EqualsPatternClass = enterSpecialPolyClass(tpnme.EQUALS_PATTERN, EmptyFlags, Seq(AnyType))
- lazy val RepeatedParamClass = specialPolyClass(tpnme.REPEATED_PARAM_CLASS, Covariant, Seq(ObjectType, SeqType))
+ lazy val RepeatedParamClass = enterSpecialPolyClass(tpnme.REPEATED_PARAM_CLASS, Covariant, Seq(ObjectType, SeqType))
// fundamental classes
lazy val StringClass = ctx.requiredClass("java.lang.String")
def StringType: Type = StringClass.typeRef
lazy val StringModule = StringClass.linkedClass
- lazy val String_+ = newMethod(StringClass, nme.raw.PLUS, methOfAny(StringType), Final)
+ lazy val String_+ = enterMethod(StringClass, nme.raw.PLUS, methOfAny(StringType), Final)
lazy val String_valueOf_Object = StringModule.info.member(nme.valueOf).suchThat(_.info.firstParamTypes match {
case List(pt) => (pt isRef AnyClass) || (pt isRef ObjectClass)
case _ => false
@@ -431,6 +485,9 @@ class Definitions {
def PartialFunctionClass(implicit ctx: Context) = PartialFunctionType.symbol.asClass
lazy val AbstractPartialFunctionType: TypeRef = ctx.requiredClassRef("scala.runtime.AbstractPartialFunction")
def AbstractPartialFunctionClass(implicit ctx: Context) = AbstractPartialFunctionType.symbol.asClass
+ lazy val FunctionXXLType: TypeRef = ctx.requiredClassRef("scala.FunctionXXL")
+ def FunctionXXLClass(implicit ctx: Context) = FunctionXXLType.symbol.asClass
+
lazy val SymbolType: TypeRef = ctx.requiredClassRef("scala.Symbol")
def SymbolClass(implicit ctx: Context) = SymbolType.symbol.asClass
lazy val DynamicType: TypeRef = ctx.requiredClassRef("scala.Dynamic")
@@ -560,16 +617,18 @@ class Definitions {
sym.owner.linkedClass.typeRef
object FunctionOf {
- def apply(args: List[Type], resultType: Type)(implicit ctx: Context) =
- FunctionType(args.length).appliedTo(args ::: resultType :: Nil)
- def unapply(ft: Type)(implicit ctx: Context)/*: Option[(List[Type], Type)]*/ = {
- // -language:keepUnions difference: unapply needs result type because inferred type
- // is Some[(List[Type], Type)] | None, which is not a legal unapply type.
+ def apply(args: List[Type], resultType: Type, isImplicit: Boolean = false)(implicit ctx: Context) =
+ FunctionType(args.length, isImplicit).appliedTo(args ::: resultType :: Nil)
+ def unapply(ft: Type)(implicit ctx: Context) = {
val tsym = ft.typeSymbol
- lazy val targs = ft.argInfos
- val numArgs = targs.length - 1
- if (numArgs >= 0 && numArgs <= MaxFunctionArity &&
- (FunctionType(numArgs).symbol == tsym)) Some(targs.init, targs.last)
+ val isImplicitFun = isImplicitFunctionClass(tsym)
+ if (isImplicitFun || isFunctionClass(tsym)) {
+ val targs = ft.argInfos
+ val numArgs = targs.length - 1
+ if (numArgs >= 0 && FunctionType(numArgs, isImplicitFun).symbol == tsym)
+ Some(targs.init, targs.last, isImplicitFun)
+ else None
+ }
else None
}
}
@@ -612,19 +671,30 @@ class Definitions {
// ----- Symbol sets ---------------------------------------------------
- lazy val AbstractFunctionType = mkArityArray("scala.runtime.AbstractFunction", MaxAbstractFunctionArity, 0)
+ lazy val AbstractFunctionType = mkArityArray("scala.runtime.AbstractFunction", MaxImplementedFunctionArity, 0)
val AbstractFunctionClassPerRun = new PerRun[Array[Symbol]](implicit ctx => AbstractFunctionType.map(_.symbol.asClass))
def AbstractFunctionClass(n: Int)(implicit ctx: Context) = AbstractFunctionClassPerRun()(ctx)(n)
- lazy val FunctionType = mkArityArray("scala.Function", MaxFunctionArity, 0)
- def FunctionClassPerRun = new PerRun[Array[Symbol]](implicit ctx => FunctionType.map(_.symbol.asClass))
- def FunctionClass(n: Int)(implicit ctx: Context) = FunctionClassPerRun()(ctx)(n)
- lazy val Function0_applyR = FunctionType(0).symbol.requiredMethodRef(nme.apply)
- def Function0_apply(implicit ctx: Context) = Function0_applyR.symbol
+ private lazy val ImplementedFunctionType = mkArityArray("scala.Function", MaxImplementedFunctionArity, 0)
+ def FunctionClassPerRun = new PerRun[Array[Symbol]](implicit ctx => ImplementedFunctionType.map(_.symbol.asClass))
lazy val TupleType = mkArityArray("scala.Tuple", MaxTupleArity, 2)
lazy val ProductNType = mkArityArray("scala.Product", MaxTupleArity, 0)
- private lazy val FunctionTypes: Set[TypeRef] = FunctionType.toSet
+ def FunctionClass(n: Int)(implicit ctx: Context) =
+ if (n < MaxImplementedFunctionArity) FunctionClassPerRun()(ctx)(n)
+ else ctx.requiredClass("scala.Function" + n.toString)
+
+ lazy val Function0_applyR = ImplementedFunctionType(0).symbol.requiredMethodRef(nme.apply)
+ def Function0_apply(implicit ctx: Context) = Function0_applyR.symbol
+
+ def ImplicitFunctionClass(n: Int)(implicit ctx: Context) =
+ ctx.requiredClass("scala.ImplicitFunction" + n.toString)
+
+ def FunctionType(n: Int, isImplicit: Boolean = false)(implicit ctx: Context): TypeRef =
+ if (isImplicit && !ctx.erasedTypes) ImplicitFunctionClass(n).typeRef
+ else if (n < MaxImplementedFunctionArity) ImplementedFunctionType(n)
+ else FunctionClass(n).typeRef
+
private lazy val TupleTypes: Set[TypeRef] = TupleType.toSet
private lazy val ProductTypes: Set[TypeRef] = ProductNType.toSet
@@ -637,7 +707,9 @@ class Definitions {
private def isVarArityClass(cls: Symbol, prefix: Name) = {
val name = scalaClassName(cls)
- name.startsWith(prefix) && name.drop(prefix.length).forall(_.isDigit)
+ name.startsWith(prefix) &&
+ name.length > prefix.length &&
+ name.drop(prefix.length).forall(_.isDigit)
}
def isBottomClass(cls: Symbol) =
@@ -646,10 +718,20 @@ class Definitions {
tp.derivesFrom(NothingClass) || tp.derivesFrom(NullClass)
def isFunctionClass(cls: Symbol) = isVarArityClass(cls, tpnme.Function)
+ def isImplicitFunctionClass(cls: Symbol) = isVarArityClass(cls, tpnme.ImplicitFunction)
+ def isUnimplementedFunctionClass(cls: Symbol) =
+ isFunctionClass(cls) && cls.name.functionArity > MaxImplementedFunctionArity
def isAbstractFunctionClass(cls: Symbol) = isVarArityClass(cls, tpnme.AbstractFunction)
def isTupleClass(cls: Symbol) = isVarArityClass(cls, tpnme.Tuple)
def isProductClass(cls: Symbol) = isVarArityClass(cls, tpnme.Product)
+ val predefClassNames: Set[Name] =
+ Set("Predef$", "DeprecatedPredef", "LowPriorityImplicits").map(_.toTypeName)
+
+ /** Is `cls` the predef module class, or a class inherited by Predef? */
+ def isPredefClass(cls: Symbol) =
+ (cls.owner eq ScalaPackageClass) && predefClassNames.contains(cls.name)
+
val StaticRootImportFns = List[() => TermRef](
() => JavaLangPackageVal.termRef,
() => ScalaPackageVal.termRef
@@ -688,13 +770,29 @@ class Definitions {
def isProductSubType(tp: Type)(implicit ctx: Context) =
(tp derivesFrom ProductType.symbol) && tp.baseClasses.exists(isProductClass)
+ def productArity(tp: Type)(implicit ctx: Context) =
+ if (tp derivesFrom ProductType.symbol)
+ tp.baseClasses.find(isProductClass) match {
+ case Some(prod) => prod.typeParams.length
+ case None => -1
+ }
+ else -1
+
+ /** Is `tp` (an alias) of either a scala.FunctionN or a scala.ImplicitFunctionN ? */
def isFunctionType(tp: Type)(implicit ctx: Context) = {
val arity = functionArity(tp)
- 0 <= arity && arity <= MaxFunctionArity && (tp isRef FunctionType(arity).symbol)
+ val sym = tp.dealias.typeSymbol
+ arity >= 0 && (
+ isFunctionClass(sym) && tp.isRef(FunctionType(arity, isImplicit = false).typeSymbol) ||
+ isImplicitFunctionClass(sym) && tp.isRef(FunctionType(arity, isImplicit = true).typeSymbol)
+ )
}
def functionArity(tp: Type)(implicit ctx: Context) = tp.dealias.argInfos.length - 1
+ def isImplicitFunctionType(tp: Type)(implicit ctx: Context) =
+ isFunctionType(tp) && tp.dealias.typeSymbol.name.startsWith(tpnme.ImplicitFunction)
+
// ----- primitive value class machinery ------------------------------------------
/** This class would also be obviated by the implicit function type design */
@@ -767,6 +865,26 @@ class Definitions {
// ----- Initialization ---------------------------------------------------
+ private def maxImplemented(name: Name) =
+ if (name `startsWith` tpnme.Function) MaxImplementedFunctionArity else 0
+
+ /** Give the scala package a scope where a FunctionN trait is automatically
+ * added when someone looks for it.
+ */
+ private def makeScalaSpecial()(implicit ctx: Context) = {
+ val oldInfo = ScalaPackageClass.classInfo
+ val oldDecls = oldInfo.decls
+ val newDecls = new MutableScope(oldDecls) {
+ override def lookupEntry(name: Name)(implicit ctx: Context): ScopeEntry = {
+ val res = super.lookupEntry(name)
+ if (res == null && name.isTypeName && name.functionArity > maxImplemented(name))
+ newScopeEntry(newFunctionNTrait(name.asTypeName))
+ else res
+ }
+ }
+ ScalaPackageClass.info = oldInfo.derivedClassInfo(decls = newDecls)
+ }
+
/** Lists core classes that don't have underlying bytecode, but are synthesized on-the-fly in every reflection universe */
lazy val syntheticScalaClasses = List(
AnyClass,
@@ -794,6 +912,8 @@ class Definitions {
def init()(implicit ctx: Context) = {
this.ctx = ctx
if (!_isInitialized) {
+ makeScalaSpecial()
+
// force initialization of every symbol that is synthesized or hijacked by the compiler
val forced = syntheticCoreClasses ++ syntheticCoreMethods ++ ScalaValueClasses()
diff --git a/compiler/src/dotty/tools/dotc/core/Denotations.scala b/compiler/src/dotty/tools/dotc/core/Denotations.scala
index 6a39c5787..99c688d50 100644
--- a/compiler/src/dotty/tools/dotc/core/Denotations.scala
+++ b/compiler/src/dotty/tools/dotc/core/Denotations.scala
@@ -132,7 +132,7 @@ object Denotations {
def atSignature(sig: Signature, site: Type = NoPrefix, relaxed: Boolean = false)(implicit ctx: Context): Denotation
/** The variant of this denotation that's current in the given context.
- * If no such denotation exists, returns the denotation with each alternative
+ * If no such denotation exists, returns the denotation with each alternative
* at its first point of definition.
*/
def current(implicit ctx: Context): Denotation
@@ -744,6 +744,20 @@ object Denotations {
else NoDenotation
}
+ /** The next defined denotation (following `nextInRun`) or an arbitrary
+ * undefined denotation, if all denotations in a `nextinRun` cycle are
+ * undefined.
+ */
+ private def nextDefined: SingleDenotation = {
+ var p1 = this
+ var p2 = nextInRun
+ while (p1.validFor == Nowhere && (p1 ne p2)) {
+ p1 = p1.nextInRun
+ p2 = p2.nextInRun.nextInRun
+ }
+ p1
+ }
+
/** Produce a denotation that is valid for the given context.
* Usually called when !(validFor contains ctx.period)
* (even though this is not a precondition).
@@ -763,8 +777,9 @@ object Denotations {
// can happen if we sit on a stale denotation which has been replaced
// wholesale by an installAfter; in this case, proceed to the next
// denotation and try again.
- if (validFor == Nowhere && nextInRun.validFor != Nowhere) return nextInRun.current
- assert(false)
+ val nxt = nextDefined
+ if (nxt.validFor != Nowhere) return nxt
+ assert(false, this)
}
if (valid.runId != currentPeriod.runId)
@@ -905,6 +920,7 @@ object Denotations {
prev.nextInRun = this
this.nextInRun = old.nextInRun
old.validFor = Nowhere
+ old.nextInRun = this
}
def staleSymbolError(implicit ctx: Context) = {
diff --git a/compiler/src/dotty/tools/dotc/core/NameOps.scala b/compiler/src/dotty/tools/dotc/core/NameOps.scala
index 4c7f5b0a9..c037d1ce7 100644
--- a/compiler/src/dotty/tools/dotc/core/NameOps.scala
+++ b/compiler/src/dotty/tools/dotc/core/NameOps.scala
@@ -188,6 +188,8 @@ object NameOps {
def errorName: N = likeTyped(name ++ nme.ERROR)
+ def directName: N = likeTyped(name ++ DIRECT_SUFFIX)
+
def freshened(implicit ctx: Context): N =
likeTyped(
if (name.isModuleClassName) name.stripModuleClassSuffix.freshened.moduleClassName
@@ -229,6 +231,15 @@ object NameOps {
}
}
+ def functionArity: Int = {
+ def test(prefix: Name): Int =
+ if (name.startsWith(prefix))
+ try name.drop(prefix.length).toString.toInt
+ catch { case ex: NumberFormatException => -1 }
+ else -1
+ test(tpnme.Function) max test(tpnme.ImplicitFunction)
+ }
+
/** The name of the generic runtime operation corresponding to an array operation */
def genericArrayOp: TermName = name match {
case nme.apply => nme.array_apply
diff --git a/compiler/src/dotty/tools/dotc/core/Periods.scala b/compiler/src/dotty/tools/dotc/core/Periods.scala
index 6efadab7f..29d9d208f 100644
--- a/compiler/src/dotty/tools/dotc/core/Periods.scala
+++ b/compiler/src/dotty/tools/dotc/core/Periods.scala
@@ -153,7 +153,7 @@ object Periods {
final val FirstPhaseId = 1
/** The number of bits needed to encode a phase identifier. */
- final val PhaseWidth = 6
+ final val PhaseWidth = 7
final val PhaseMask = (1 << PhaseWidth) - 1
final val MaxPossiblePhaseId = PhaseMask
}
diff --git a/compiler/src/dotty/tools/dotc/core/Phases.scala b/compiler/src/dotty/tools/dotc/core/Phases.scala
index 222e2235d..6a53e1b30 100644
--- a/compiler/src/dotty/tools/dotc/core/Phases.scala
+++ b/compiler/src/dotty/tools/dotc/core/Phases.scala
@@ -26,7 +26,10 @@ trait Phases {
def phasesStack: List[Phase] =
if ((this eq NoContext) || !phase.exists) Nil
- else phase :: outersIterator.dropWhile(_.phase == phase).next.phasesStack
+ else {
+ val rest = outersIterator.dropWhile(_.phase == phase)
+ phase :: (if (rest.hasNext) rest.next.phasesStack else Nil)
+ }
/** Execute `op` at given phase */
def atPhase[T](phase: Phase)(op: Context => T): T =
diff --git a/compiler/src/dotty/tools/dotc/core/Scopes.scala b/compiler/src/dotty/tools/dotc/core/Scopes.scala
index 3daa8117e..6090079e5 100644
--- a/compiler/src/dotty/tools/dotc/core/Scopes.scala
+++ b/compiler/src/dotty/tools/dotc/core/Scopes.scala
@@ -309,7 +309,7 @@ object Scopes {
/** Lookup a symbol entry matching given name.
*/
- override final def lookupEntry(name: Name)(implicit ctx: Context): ScopeEntry = {
+ override def lookupEntry(name: Name)(implicit ctx: Context): ScopeEntry = {
var e: ScopeEntry = null
if (hashTable ne null) {
e = hashTable(name.hashCode & (hashTable.length - 1))
diff --git a/compiler/src/dotty/tools/dotc/core/StdNames.scala b/compiler/src/dotty/tools/dotc/core/StdNames.scala
index c2a14b36f..716959648 100644
--- a/compiler/src/dotty/tools/dotc/core/StdNames.scala
+++ b/compiler/src/dotty/tools/dotc/core/StdNames.scala
@@ -129,6 +129,7 @@ object StdNames {
val COMPANION_MODULE_METHOD: N = "companion$module"
val COMPANION_CLASS_METHOD: N = "companion$class"
val TRAIT_SETTER_SEPARATOR: N = "$_setter_$"
+ val DIRECT_SUFFIX: N = "$direct"
// value types (and AnyRef) are all used as terms as well
// as (at least) arguments to the @specialize annotation.
@@ -181,6 +182,7 @@ object StdNames {
final val AnyVal: N = "AnyVal"
final val ExprApi: N = "ExprApi"
final val Function: N = "Function"
+ final val ImplicitFunction: N = "ImplicitFunction"
final val Mirror: N = "Mirror"
final val Nothing: N = "Nothing"
final val Null: N = "Null"
@@ -265,6 +267,7 @@ object StdNames {
val THIS: N = "_$this"
val TRAIT_CONSTRUCTOR: N = "$init$"
val U2EVT: N = "u2evt$"
+ val ALLARGS: N = "$allArgs"
final val Nil: N = "Nil"
final val Predef: N = "Predef"
@@ -423,7 +426,6 @@ object StdNames {
val info: N = "info"
val inlinedEquals: N = "inlinedEquals"
val isArray: N = "isArray"
- val isDefined: N = "isDefined"
val isDefinedAt: N = "isDefinedAt"
val isDefinedAtImpl: N = "$isDefinedAt"
val isEmpty: N = "isEmpty"
diff --git a/compiler/src/dotty/tools/dotc/core/SymDenotations.scala b/compiler/src/dotty/tools/dotc/core/SymDenotations.scala
index 8b7c28e19..aaae78c57 100644
--- a/compiler/src/dotty/tools/dotc/core/SymDenotations.scala
+++ b/compiler/src/dotty/tools/dotc/core/SymDenotations.scala
@@ -75,7 +75,7 @@ trait SymDenotations { this: Context =>
def explainSym(msg: String) = explain(s"$msg\n defined = ${denot.definedPeriodsString}")
if (denot.is(ValidForever) || denot.isRefinementClass) true
else {
- implicit val ctx: Context = this
+ implicit val ctx = this
val initial = denot.initial
if ((initial ne denot) || ctx.phaseId != initial.validFor.firstPhaseId) {
ctx.withPhase(initial.validFor.firstPhaseId).traceInvalid(initial)
@@ -1937,12 +1937,12 @@ object SymDenotations {
/** A completer for missing references */
class StubInfo() extends LazyType {
- def initializeToDefaults(denot: SymDenotation)(implicit ctx: Context) = {
+ def initializeToDefaults(denot: SymDenotation, errMsg: => String)(implicit ctx: Context) = {
denot.info = denot match {
case denot: ClassDenotation =>
ClassInfo(denot.owner.thisType, denot.classSymbol, Nil, EmptyScope)
case _ =>
- ErrorType
+ new ErrorType(errMsg)
}
denot.privateWithin = NoSymbol
}
@@ -1954,13 +1954,14 @@ object SymDenotations {
if (file != null) (s" in $file", file.toString)
else ("", "the signature")
val name = ctx.fresh.setSetting(ctx.settings.debugNames, true).nameString(denot.name)
- ctx.error(
+ def errMsg =
i"""bad symbolic reference. A signature$location
|refers to $name in ${denot.owner.showKind} ${denot.owner.showFullName} which is not available.
|It may be completely missing from the current classpath, or the version on
- |the classpath might be incompatible with the version used when compiling $src.""")
+ |the classpath might be incompatible with the version used when compiling $src."""
+ ctx.error(errMsg)
if (ctx.debug) throw new Error()
- initializeToDefaults(denot)
+ initializeToDefaults(denot, errMsg)
}
}
diff --git a/compiler/src/dotty/tools/dotc/core/Symbols.scala b/compiler/src/dotty/tools/dotc/core/Symbols.scala
index cfd85c49c..5d0dd2123 100644
--- a/compiler/src/dotty/tools/dotc/core/Symbols.scala
+++ b/compiler/src/dotty/tools/dotc/core/Symbols.scala
@@ -22,6 +22,7 @@ import NameOps._
import ast.tpd.Tree
import ast.TreeTypeMap
import Constants.Constant
+import reporting.diagnostic.Message
import Denotations.{ Denotation, SingleDenotation, MultiDenotation }
import collection.mutable
import io.AbstractFile
@@ -290,9 +291,11 @@ trait Symbols { this: Context =>
*/
def newSkolem(tp: Type) = newSymbol(defn.RootClass, nme.SKOLEM, SyntheticArtifact | Permanent, tp)
- def newErrorSymbol(owner: Symbol, name: Name) =
+ def newErrorSymbol(owner: Symbol, name: Name, msg: => Message) = {
+ val errType = new ErrorType(msg)
newSymbol(owner, name, SyntheticArtifact,
- if (name.isTypeName) TypeAlias(ErrorType) else ErrorType)
+ if (name.isTypeName) TypeAlias(errType) else errType)
+ }
/** Map given symbols, subjecting their attributes to the mappings
* defined in the given TreeTypeMap `ttmap`.
@@ -313,10 +316,7 @@ trait Symbols { this: Context =>
newNakedSymbol[original.ThisName](original.coord)
}
val ttmap1 = ttmap.withSubstitution(originals, copies)
- (originals, copies).zipped foreach {(original, copy) =>
- copy.denot = original.denot // preliminary denotation, so that we can access symbols in subsequent transform
- }
- (originals, copies).zipped foreach {(original, copy) =>
+ (originals, copies).zipped foreach { (original, copy) =>
val odenot = original.denot
val oinfo = original.info match {
case ClassInfo(pre, _, parents, decls, selfInfo) =>
@@ -324,14 +324,27 @@ trait Symbols { this: Context =>
ClassInfo(pre, copy.asClass, parents, decls.cloneScope, selfInfo)
case oinfo => oinfo
}
+
+ val completer = new LazyType {
+ def complete(denot: SymDenotation)(implicit ctx: Context): Unit = {
+ denot.info = oinfo // needed as otherwise we won't be able to go from Sym -> parents & etc
+ // Note that this is a hack, but hack commonly used in Dotty
+ // The same thing is done by other completers all the time
+ denot.info = ttmap1.mapType(oinfo)
+ denot.annotations = odenot.annotations.mapConserve(ttmap1.apply)
+ }
+ }
+
copy.denot = odenot.copySymDenotation(
symbol = copy,
owner = ttmap1.mapOwner(odenot.owner),
- initFlags = odenot.flags &~ Frozen | Fresh,
- info = ttmap1.mapType(oinfo),
+ initFlags = odenot.flags &~ (Frozen | Touched) | Fresh,
+ info = completer,
privateWithin = ttmap1.mapOwner(odenot.privateWithin), // since this refers to outer symbols, need not include copies (from->to) in ownermap here.
- annotations = odenot.annotations.mapConserve(ttmap1.apply))
+ annotations = odenot.annotations)
+
}
+
copies
}
@@ -390,6 +403,10 @@ object Symbols {
denot
}
+ /** The initial denotation of this symbol, without going through `current` */
+ final def initialDenot(implicit ctx: Context): SymDenotation =
+ lastDenot.initial
+
private[core] def defRunId: RunId =
if (lastDenot == null) NoRunId else lastDenot.validFor.runId
diff --git a/compiler/src/dotty/tools/dotc/core/TypeComparer.scala b/compiler/src/dotty/tools/dotc/core/TypeComparer.scala
index f78820fff..6063cbf38 100644
--- a/compiler/src/dotty/tools/dotc/core/TypeComparer.scala
+++ b/compiler/src/dotty/tools/dotc/core/TypeComparer.scala
@@ -16,7 +16,7 @@ import scala.util.control.NonFatal
/** Provides methods to compare types.
*/
class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
- implicit val ctx: Context = initctx
+ implicit val ctx = initctx
val state = ctx.typerState
import state.constraint
@@ -156,7 +156,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
private def firstTry(tp1: Type, tp2: Type): Boolean = tp2 match {
case tp2: NamedType =>
def compareNamed(tp1: Type, tp2: NamedType): Boolean = {
- implicit val ctx: Context = this.ctx
+ implicit val ctx = this.ctx
tp2.info match {
case info2: TypeAlias => isSubType(tp1, info2.alias)
case _ => tp1 match {
@@ -260,7 +260,12 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
secondTry(tp1, tp2)
}
compareErasedValueType
- case ErrorType =>
+ case ConstantType(v2) =>
+ tp1 match {
+ case ConstantType(v1) => v1.value == v2.value
+ case _ => secondTry(tp1, tp2)
+ }
+ case _: FlexType =>
true
case _ =>
secondTry(tp1, tp2)
@@ -336,7 +341,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
false
}
joinOK || isSubType(tp11, tp2) && isSubType(tp12, tp2)
- case ErrorType =>
+ case _: FlexType =>
true
case _ =>
thirdTry(tp1, tp2)
@@ -370,11 +375,22 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
thirdTryNamed(tp1, tp2)
case tp2: PolyParam =>
def comparePolyParam =
- (ctx.mode is Mode.TypevarsMissContext) ||
- isSubTypeWhenFrozen(tp1, bounds(tp2).lo) || {
+ (ctx.mode is Mode.TypevarsMissContext) || {
+ val alwaysTrue =
+ // The following condition is carefully formulated to catch all cases
+ // where the subtype relation is true without needing to add a constraint
+ // It's tricky because we might need to either appriximate tp2 by its
+ // lower bound or else widen tp1 and check that the result is a subtype of tp2.
+ // So if the constraint is not yet frozen, we do the same comparison again
+ // with a frozen constraint, which means that we get a chance to do the
+ // widening in `fourthTry` before adding to the constraint.
+ if (frozenConstraint || alwaysFluid) isSubType(tp1, bounds(tp2).lo)
+ else isSubTypeWhenFrozen(tp1, tp2)
+ alwaysTrue || {
if (canConstrain(tp2)) addConstraint(tp2, tp1.widenExpr, fromBelow = true)
else fourthTry(tp1, tp2)
}
+ }
comparePolyParam
case tp2: RefinedType =>
def compareRefinedSlow: Boolean = {
@@ -473,7 +489,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
case tp1 @ MethodType(_, formals1) =>
(tp1.signature consistentParams tp2.signature) &&
matchingParams(formals1, formals2, tp1.isJava, tp2.isJava) &&
- tp1.isImplicit == tp2.isImplicit && // needed?
+ (!tp1.isImplicit || tp2.isImplicit) && // non-implicit functions shadow implicit ones
isSubType(tp1.resultType, tp2.resultType.subst(tp2, tp1))
case _ =>
false
@@ -541,9 +557,11 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
/** if `tp2 == p.type` and `p: q.type` then try `tp1 <:< q.type` as a last effort.*/
def comparePaths = tp2 match {
case tp2: TermRef =>
- tp2.info.widenExpr match {
+ tp2.info.widenExpr.dealias match {
case tp2i: SingletonType =>
- isSubType(tp1, tp2i) // see z1720.scala for a case where this can arise even in typer.
+ isSubType(tp1, tp2i)
+ // see z1720.scala for a case where this can arise even in typer.
+ // Also, i1753.scala, to show why the dealias above is necessary.
case _ => false
}
case _ =>
@@ -750,8 +768,14 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
if (args1.isEmpty) args2.isEmpty
else args2.nonEmpty && {
val v = tparams.head.paramVariance
- (v > 0 || isSubType(args2.head, args1.head)) &&
- (v < 0 || isSubType(args1.head, args2.head))
+ def isSub(tp1: Type, tp2: Type) = tp2 match {
+ case tp2: TypeBounds =>
+ tp2.contains(tp1)
+ case _ =>
+ (v > 0 || isSubType(tp2, tp1)) &&
+ (v < 0 || isSubType(tp1, tp2))
+ }
+ isSub(args1.head, args2.head)
} && isSubArgs(args1.tail, args2.tail, tparams)
/** Test whether `tp1` has a base type of the form `B[T1, ..., Tn]` where
@@ -996,9 +1020,9 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
case tp1: MethodType =>
tp2.widen match {
case tp2: MethodType =>
- tp1.isImplicit == tp2.isImplicit &&
- matchingParams(tp1.paramTypes, tp2.paramTypes, tp1.isJava, tp2.isJava) &&
- matchesType(tp1.resultType, tp2.resultType.subst(tp2, tp1), relaxed)
+ // implicitness is ignored when matching
+ matchingParams(tp1.paramTypes, tp2.paramTypes, tp1.isJava, tp2.isJava) &&
+ matchesType(tp1.resultType, tp2.resultType.subst(tp2, tp1), relaxed)
case tp2 =>
relaxed && tp1.paramNames.isEmpty &&
matchesType(tp1.resultType, tp2, relaxed)
diff --git a/compiler/src/dotty/tools/dotc/core/TypeErasure.scala b/compiler/src/dotty/tools/dotc/core/TypeErasure.scala
index abbacee49..91e37d440 100644
--- a/compiler/src/dotty/tools/dotc/core/TypeErasure.scala
+++ b/compiler/src/dotty/tools/dotc/core/TypeErasure.scala
@@ -2,11 +2,14 @@ package dotty.tools
package dotc
package core
-import Symbols._, Types._, Contexts._, Flags._, Names._, StdNames._, Decorators._, Flags.JavaDefined
+import Symbols._, Types._, Contexts._, Flags._, Names._, StdNames._, Decorators._
+import Flags.JavaDefined
+import NameOps._
import Uniques.unique
import dotc.transform.ExplicitOuter._
import dotc.transform.ValueClasses._
import util.DotClass
+import Definitions.MaxImplementedFunctionArity
/** Erased types are:
*
@@ -38,7 +41,10 @@ object TypeErasure {
case _: ErasedValueType =>
true
case tp: TypeRef =>
- tp.symbol.isClass && tp.symbol != defn.AnyClass && tp.symbol != defn.ArrayClass
+ val sym = tp.symbol
+ sym.isClass &&
+ sym != defn.AnyClass && sym != defn.ArrayClass &&
+ !defn.isUnimplementedFunctionClass(sym) && !defn.isImplicitFunctionClass(sym)
case _: TermRef =>
true
case JavaArrayType(elem) =>
@@ -51,7 +57,7 @@ object TypeErasure {
tp.paramTypes.forall(isErasedType) && isErasedType(tp.resultType)
case tp @ ClassInfo(pre, _, parents, decls, _) =>
isErasedType(pre) && parents.forall(isErasedType) //&& decls.forall(sym => isErasedType(sym.info)) && isErasedType(tp.selfType)
- case NoType | NoPrefix | WildcardType | ErrorType | SuperType(_, _) =>
+ case NoType | NoPrefix | WildcardType | _: ErrorType | SuperType(_, _) =>
true
case _ =>
false
@@ -176,8 +182,13 @@ object TypeErasure {
else if (sym.isAbstractType) TypeAlias(WildcardType)
else if (sym.isConstructor) outer.addParam(sym.owner.asClass, erase(tp)(erasureCtx))
else erase.eraseInfo(tp, sym)(erasureCtx) match {
- case einfo: MethodType if sym.isGetter && einfo.resultType.isRef(defn.UnitClass) =>
- MethodType(Nil, defn.BoxedUnitType)
+ case einfo: MethodType =>
+ if (sym.isGetter && einfo.resultType.isRef(defn.UnitClass))
+ MethodType(Nil, defn.BoxedUnitType)
+ else if (sym.isAnonymousFunction && einfo.paramTypes.length > MaxImplementedFunctionArity)
+ MethodType(nme.ALLARGS :: Nil, JavaArrayType(defn.ObjectType) :: Nil, einfo.resultType)
+ else
+ einfo
case einfo =>
einfo
}
@@ -317,6 +328,8 @@ class TypeErasure(isJava: Boolean, semiEraseVCs: Boolean, isConstructor: Boolean
* - For a term ref p.x, the type <noprefix> # x.
* - For a typeref scala.Any, scala.AnyVal or scala.Singleton: |java.lang.Object|
* - For a typeref scala.Unit, |scala.runtime.BoxedUnit|.
+ * - For a typeref scala.FunctionN, where N > MaxImplementedFunctionArity, scala.FunctionXXL
+ * - For a typeref scala.ImplicitFunctionN, | scala.FunctionN |
* - For a typeref P.C where C refers to a class, <noprefix> # C.
* - For a typeref P.C where C refers to an alias type, the erasure of C's alias.
* - For a typeref P.C where C refers to an abstract type, the erasure of C's upper bound.
@@ -345,6 +358,8 @@ class TypeErasure(isJava: Boolean, semiEraseVCs: Boolean, isConstructor: Boolean
if (!sym.isClass) this(tp.info)
else if (semiEraseVCs && isDerivedValueClass(sym)) eraseDerivedValueClassRef(tp)
else if (sym == defn.ArrayClass) apply(tp.appliedTo(TypeBounds.empty)) // i966 shows that we can hit a raw Array type.
+ else if (defn.isUnimplementedFunctionClass(sym)) defn.FunctionXXLType
+ else if (defn.isImplicitFunctionClass(sym)) apply(defn.FunctionType(sym.name.functionArity))
else eraseNormalClassRef(tp)
case tp: RefinedType =>
val parent = tp.parent
@@ -387,7 +402,7 @@ class TypeErasure(isJava: Boolean, semiEraseVCs: Boolean, isConstructor: Boolean
tp.derivedClassInfo(NoPrefix, parents, erasedDecls, erasedRef(tp.selfType))
// can't replace selftype by NoType because this would lose the sourceModule link
}
- case NoType | NoPrefix | ErrorType | JavaArrayType(_) =>
+ case NoType | NoPrefix | _: ErrorType | JavaArrayType(_) =>
tp
case tp: WildcardType if wildcardOK =>
tp
@@ -427,7 +442,7 @@ class TypeErasure(isJava: Boolean, semiEraseVCs: Boolean, isConstructor: Boolean
private def eraseDerivedValueClassRef(tref: TypeRef)(implicit ctx: Context): Type = {
val cls = tref.symbol.asClass
val underlying = underlyingOfValueClass(cls)
- if (underlying.exists) ErasedValueType(tref, valueErasure(underlying))
+ if (underlying.exists && !isCyclic(cls)) ErasedValueType(tref, valueErasure(underlying))
else NoType
}
@@ -481,7 +496,10 @@ class TypeErasure(isJava: Boolean, semiEraseVCs: Boolean, isConstructor: Boolean
val erasedVCRef = eraseDerivedValueClassRef(tp)
if (erasedVCRef.exists) return sigName(erasedVCRef)
}
- normalizeClass(sym.asClass).fullName.asTypeName
+ if (defn.isImplicitFunctionClass(sym))
+ sigName(defn.FunctionType(sym.name.functionArity))
+ else
+ normalizeClass(sym.asClass).fullName.asTypeName
case defn.ArrayOf(elem) =>
sigName(this(tp))
case JavaArrayType(elem) =>
@@ -495,7 +513,7 @@ class TypeErasure(isJava: Boolean, semiEraseVCs: Boolean, isConstructor: Boolean
if (inst.exists) sigName(inst) else tpnme.Uninstantiated
case tp: TypeProxy =>
sigName(tp.underlying)
- case ErrorType | WildcardType =>
+ case _: ErrorType | WildcardType =>
tpnme.WILDCARD
case tp: WildcardType =>
sigName(tp.optBounds)
diff --git a/compiler/src/dotty/tools/dotc/core/TypeOps.scala b/compiler/src/dotty/tools/dotc/core/TypeOps.scala
index 92e5f9d57..c2a7d7ea6 100644
--- a/compiler/src/dotty/tools/dotc/core/TypeOps.scala
+++ b/compiler/src/dotty/tools/dotc/core/TypeOps.scala
@@ -10,7 +10,8 @@ import NameOps._
import Decorators._
import StdNames._
import Annotations._
-import util.SimpleMap
+import config.Config
+import util.{SimpleMap, Property}
import collection.mutable
import ast.tpd._
@@ -67,7 +68,10 @@ trait TypeOps { this: Context => // TODO: Make standalone object.
if (thiscls.derivesFrom(cls) && pre.baseTypeRef(thiscls).exists) {
if (theMap != null && theMap.currentVariance <= 0 && !isLegalPrefix(pre)) {
ctx.base.unsafeNonvariant = ctx.runId
- AnnotatedType(pre, Annotation(defn.UnsafeNonvariantAnnot, Nil))
+ pre match {
+ case AnnotatedType(_, ann) if ann.symbol == defn.UnsafeNonvariantAnnot => pre
+ case _ => AnnotatedType(pre, Annotation(defn.UnsafeNonvariantAnnot, Nil))
+ }
}
else pre
}
@@ -85,13 +89,15 @@ trait TypeOps { this: Context => // TODO: Make standalone object.
if (sym.isStatic) tp
else {
val pre1 = asSeenFrom(tp.prefix, pre, cls, theMap)
- if (pre1.isUnsafeNonvariant)
- pre1.member(tp.name).info match {
+ if (pre1.isUnsafeNonvariant) {
+ val safeCtx = ctx.withProperty(TypeOps.findMemberLimit, Some(()))
+ pre1.member(tp.name)(safeCtx).info match {
case TypeAlias(alias) =>
// try to follow aliases of this will avoid skolemization.
return alias
case _ =>
}
+ }
tp.derivedSelect(pre1)
}
case tp: ThisType =>
@@ -197,6 +203,9 @@ trait TypeOps { this: Context => // TODO: Make standalone object.
case c :: rest =>
val accu1 = if (accu exists (_ derivesFrom c)) accu else c :: accu
if (cs == c.baseClasses) accu1 else dominators(rest, accu1)
+ case Nil => // this case can happen because after erasure we do not have a top class anymore
+ assert(ctx.erasedTypes)
+ defn.ObjectClass :: Nil
}
def mergeRefined(tp1: Type, tp2: Type): Type = {
@@ -430,7 +439,7 @@ trait TypeOps { this: Context => // TODO: Make standalone object.
formals = formals.updated(name, tp1.typeParamNamed(name))
}
normalizeToRef(tp1)
- case ErrorType =>
+ case _: ErrorType =>
defn.AnyType
case AnnotatedType(tpe, _) =>
normalizeToRef(tpe)
@@ -543,7 +552,7 @@ trait TypeOps { this: Context => // TODO: Make standalone object.
def dynamicsEnabled =
featureEnabled(defn.LanguageModuleClass, nme.dynamics)
- def testScala2Mode(msg: String, pos: Position) = {
+ def testScala2Mode(msg: => String, pos: Position) = {
if (scala2Mode) migrationWarning(msg, pos)
scala2Mode
}
@@ -551,4 +560,10 @@ trait TypeOps { this: Context => // TODO: Make standalone object.
object TypeOps {
@sharable var track = false // !!!DEBUG
+
+ /** When a property with this key is set in a context, it limit the number
+ * of recursive member searches. If the limit is reached, findMember returns
+ * NoDenotation.
+ */
+ val findMemberLimit = new Property.Key[Unit]
}
diff --git a/compiler/src/dotty/tools/dotc/core/Types.scala b/compiler/src/dotty/tools/dotc/core/Types.scala
index 89bc21929..636204f64 100644
--- a/compiler/src/dotty/tools/dotc/core/Types.scala
+++ b/compiler/src/dotty/tools/dotc/core/Types.scala
@@ -15,9 +15,10 @@ import SymDenotations._
import Decorators._
import Denotations._
import Periods._
-import util.Positions.Position
+import util.Positions.{Position, NoPosition}
import util.Stats._
import util.{DotClass, SimpleMap}
+import reporting.diagnostic.Message
import ast.tpd._
import ast.TreeTypeMap
import printing.Texts._
@@ -176,7 +177,7 @@ object Types {
/** Is this type produced as a repair for an error? */
final def isError(implicit ctx: Context): Boolean = stripTypeVar match {
- case ErrorType => true
+ case _: ErrorType => true
case tp => (tp.typeSymbol is Erroneous) || (tp.termSymbol is Erroneous)
}
@@ -216,6 +217,14 @@ object Types {
case _ => false
}
+ /** Is this the type of a method with a leading empty parameter list?
+ */
+ def isNullaryMethod(implicit ctx: Context): Boolean = this match {
+ case MethodType(Nil, _) => true
+ case tp: PolyType => tp.resultType.isNullaryMethod
+ case _ => false
+ }
+
/** Is this an alias TypeBounds? */
def isAlias: Boolean = this.isInstanceOf[TypeAlias]
@@ -387,8 +396,8 @@ object Types {
tp.decls.denotsNamed(name).filterExcluded(excluded).toDenot(NoPrefix)
case tp: TypeProxy =>
tp.underlying.findDecl(name, excluded)
- case ErrorType =>
- ctx.newErrorSymbol(classSymbol orElse defn.RootClass, name)
+ case err: ErrorType =>
+ ctx.newErrorSymbol(classSymbol orElse defn.RootClass, name, err.msg)
case _ =>
NoDenotation
}
@@ -453,8 +462,8 @@ object Types {
go(tp.join)
case tp: JavaArrayType =>
defn.ObjectType.findMember(name, pre, excluded)
- case ErrorType =>
- ctx.newErrorSymbol(pre.classSymbol orElse defn.RootClass, name)
+ case err: ErrorType =>
+ ctx.newErrorSymbol(pre.classSymbol orElse defn.RootClass, name, err.msg)
case _ =>
NoDenotation
}
@@ -572,8 +581,12 @@ object Types {
{ val recCount = ctx.findMemberCount + 1
ctx.findMemberCount = recCount
- if (recCount >= Config.LogPendingFindMemberThreshold)
+ if (recCount >= Config.LogPendingFindMemberThreshold) {
ctx.pendingMemberSearches = name :: ctx.pendingMemberSearches
+ if (ctx.property(TypeOps.findMemberLimit).isDefined &&
+ ctx.findMemberCount > Config.PendingFindMemberLimit)
+ return NoDenotation
+ }
}
//assert(ctx.findMemberCount < 20)
@@ -1210,7 +1223,7 @@ object Types {
case mt @ MethodType(_, formals) if !mt.isDependent || ctx.mode.is(Mode.AllowDependentFunctions) =>
val formals1 = if (dropLast == 0) formals else formals dropRight dropLast
defn.FunctionOf(
- formals1 mapConserve (_.underlyingIfRepeated(mt.isJava)), mt.resultType)
+ formals1 mapConserve (_.underlyingIfRepeated(mt.isJava)), mt.resultType, mt.isImplicit && !ctx.erasedTypes)
}
/** The signature of this type. This is by default NotAMethod,
@@ -1497,7 +1510,7 @@ object Types {
(lastDefRunId != sym.defRunId) ||
(lastDefRunId == NoRunId)
} ||
- (lastSymbol.infoOrCompleter == ErrorType ||
+ (lastSymbol.infoOrCompleter.isInstanceOf[ErrorType] ||
sym.owner != lastSymbol.owner &&
(sym.owner.derivesFrom(lastSymbol.owner) ||
selfTypeOf(sym).derivesFrom(lastSymbol.owner) ||
@@ -2275,11 +2288,13 @@ object Types {
protected def resultSignature(implicit ctx: Context) = try resultType match {
case rtp: MethodicType => rtp.signature
- case tp => Signature(tp, isJava = false)
+ case tp =>
+ if (tp.isRef(defn.UnitClass)) Signature(Nil, defn.UnitClass.fullName.asTypeName)
+ else Signature(tp, isJava = false)
}
catch {
case ex: AssertionError =>
- println(i"failure while taking result signture of $this: $resultType")
+ println(i"failure while taking result signature of $this: $resultType")
throw ex
}
@@ -2376,7 +2391,9 @@ object Types {
protected def computeSignature(implicit ctx: Context): Signature =
resultSignature.prepend(paramTypes, isJava)
- def derivedMethodType(paramNames: List[TermName], paramTypes: List[Type], resType: Type)(implicit ctx: Context) =
+ def derivedMethodType(paramNames: List[TermName] = this.paramNames,
+ paramTypes: List[Type] = this.paramTypes,
+ resType: Type = this.resType)(implicit ctx: Context) =
if ((paramNames eq this.paramNames) && (paramTypes eq this.paramTypes) && (resType eq this.resType)) this
else {
val resTypeFn = (x: MethodType) => resType.subst(this, x)
@@ -2693,7 +2710,7 @@ object Types {
protected def checkInst(implicit ctx: Context): this.type = {
def check(tycon: Type): Unit = tycon.stripTypeVar match {
case tycon: TypeRef if !tycon.symbol.isClass =>
- case _: PolyParam | ErrorType | _: WildcardType =>
+ case _: PolyParam | _: ErrorType | _: WildcardType =>
case _: PolyType =>
assert(args.exists(_.isInstanceOf[TypeBounds]), s"unreduced type apply: $this")
case tycon: AnnotatedType =>
@@ -2862,14 +2879,14 @@ object Types {
*
* @param origin The parameter that's tracked by the type variable.
* @param creatorState The typer state in which the variable was created.
- * @param owningTree The function part of the TypeApply tree tree that introduces
- * the type variable.
+ * @param bindingTree The TypeTree which introduces the type variable, or EmptyTree
+ * if the type variable does not correspond to a source term.
* @paran owner The current owner if the context where the variable was created.
*
* `owningTree` and `owner` are used to determine whether a type-variable can be instantiated
* at some given point. See `Inferencing#interpolateUndetVars`.
*/
- final class TypeVar(val origin: PolyParam, creatorState: TyperState, val owningTree: untpd.Tree, val owner: Symbol) extends CachedProxyType with ValueType {
+ final class TypeVar(val origin: PolyParam, creatorState: TyperState, val bindingTree: untpd.Tree, val owner: Symbol) extends CachedProxyType with ValueType {
/** The permanent instance type of the variable, or NoType is none is given yet */
private[core] var inst: Type = NoType
@@ -3251,12 +3268,19 @@ object Types {
override def computeHash = hashSeed
}
- abstract class ErrorType extends UncachedGroundType with ValueType
+ /** A common superclass of `ErrorType` and `TryDynamicCallSite`. Instances of this
+ * class are at the same time subtypes and supertypes of every other type.
+ */
+ abstract class FlexType extends UncachedGroundType with ValueType
+
+ class ErrorType(_msg: => Message) extends FlexType {
+ val msg = _msg
+ }
- object ErrorType extends ErrorType
+ object UnspecifiedErrorType extends ErrorType("unspecified error")
/* Type used to track Select nodes that could not resolve a member and their qualifier is a scala.Dynamic. */
- object TryDynamicCallType extends ErrorType
+ object TryDynamicCallType extends FlexType
/** Wildcard type, possibly with bounds */
abstract case class WildcardType(optBounds: Type) extends CachedGroundType with TermType {
@@ -3378,7 +3402,7 @@ object Types {
/** Map this function over given type */
def mapOver(tp: Type): Type = {
- implicit val ctx: Context = this.ctx // Dotty deviation: implicits need explicit type
+ implicit val ctx = this.ctx
tp match {
case tp: NamedType =>
if (stopAtStatic && tp.symbol.isStatic) tp
diff --git a/compiler/src/dotty/tools/dotc/parsing/JavaParsers.scala b/compiler/src/dotty/tools/dotc/parsing/JavaParsers.scala
index 0f63b25bb..92ab10db9 100644
--- a/compiler/src/dotty/tools/dotc/parsing/JavaParsers.scala
+++ b/compiler/src/dotty/tools/dotc/parsing/JavaParsers.scala
@@ -90,7 +90,8 @@ object JavaParsers {
if (skipIt)
skip()
}
- def errorTypeTree = TypeTree().withType(ErrorType) withPos Position(in.offset)
+
+ def errorTypeTree = TypeTree().withType(UnspecifiedErrorType) withPos Position(in.offset)
// --------- tree building -----------------------------
diff --git a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala
index fa0576c7a..f62093db0 100644
--- a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala
+++ b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala
@@ -83,6 +83,15 @@ object Parsers {
def atPos[T <: Positioned](start: Offset)(t: T): T =
atPos(start, start)(t)
+ def startOffset(t: Positioned): Int =
+ if (t.pos.exists) t.pos.start else in.offset
+
+ def pointOffset(t: Positioned): Int =
+ if (t.pos.exists) t.pos.point else in.offset
+
+ def endOffset(t: Positioned): Int =
+ if (t.pos.exists) t.pos.end else in.lastOffset
+
def nameStart: Offset =
if (in.token == BACKQUOTED_IDENT) in.offset + 1 else in.offset
@@ -137,6 +146,7 @@ object Parsers {
def isNumericLit = numericLitTokens contains in.token
def isModifier = modifierTokens contains in.token
def isExprIntro = canStartExpressionTokens contains in.token
+ def isBindingIntro = canStartBindingTokens contains in.token
def isTemplateIntro = templateIntroTokens contains in.token
def isDclIntro = dclIntroTokens contains in.token
def isStatSeqEnd = in.token == RBRACE || in.token == EOF
@@ -448,7 +458,7 @@ object Parsers {
val topInfo = opStack.head
opStack = opStack.tail
val od = reduceStack(base, topInfo.operand, 0, true)
- return atPos(od.pos.start, topInfo.offset) {
+ return atPos(startOffset(od), topInfo.offset) {
PostfixOp(od, topInfo.operator)
}
}
@@ -492,9 +502,9 @@ object Parsers {
/** Accept identifier acting as a selector on given tree `t`. */
def selector(t: Tree): Tree =
- atPos(t.pos.start, in.offset) { Select(t, ident()) }
+ atPos(startOffset(t), in.offset) { Select(t, ident()) }
- /** Selectors ::= ident { `.' ident()
+ /** Selectors ::= id { `.' id }
*
* Accept `.' separated identifiers acting as a selectors on given tree `t`.
* @param finish An alternative parse in case the next token is not an identifier.
@@ -505,7 +515,7 @@ object Parsers {
if (t1 ne t) t1 else dotSelectors(selector(t), finish)
}
- /** DotSelectors ::= { `.' ident()
+ /** DotSelectors ::= { `.' id }
*
* Accept `.' separated identifiers acting as a selectors on given tree `t`.
* @param finish An alternative parse in case the token following a `.' is not an identifier.
@@ -518,9 +528,9 @@ object Parsers {
private val id: Tree => Tree = x => x
/** Path ::= StableId
- * | [Ident `.'] this
+ * | [id `.'] this
*
- * @param thisOK If true, [Ident `.'] this is acceptable as the path.
+ * @param thisOK If true, the path can end with the keyword `this`.
* If false, another selection is required after the `this`.
* @param finish An alternative parse in case the token following a `.' is not an identifier.
* If the alternative does not apply, its tree argument is returned unchanged.
@@ -530,7 +540,7 @@ object Parsers {
def handleThis(qual: Ident) = {
in.nextToken()
val t = atPos(start) { This(qual) }
- if (!thisOK && in.token != DOT) syntaxError("`.' expected")
+ if (!thisOK && in.token != DOT) syntaxError(DanglingThisInPath(), t.pos)
dotSelectors(t, finish)
}
def handleSuper(qual: Ident) = {
@@ -555,20 +565,20 @@ object Parsers {
}
}
- /** MixinQualifier ::= `[' Id `]'
+ /** MixinQualifier ::= `[' id `]'
*/
def mixinQualifierOpt(): Ident =
if (in.token == LBRACKET) inBrackets(atPos(in.offset) { typeIdent() })
else EmptyTypeIdent
- /** StableId ::= Id
- * | Path `.' Id
+ /** StableId ::= id
+ * | Path `.' id
* | [id '.'] super [`[' id `]']`.' id
*/
def stableId(): Tree =
path(thisOK = false)
- /** QualId ::= Id {`.' Id}
+ /** QualId ::= id {`.' id}
*/
def qualId(): Tree =
dotSelectors(termIdent())
@@ -588,7 +598,7 @@ object Parsers {
val isNegated = negOffset < in.offset
atPos(negOffset) {
if (in.token == SYMBOLLIT) atPos(in.skipToken()) { SymbolLit(in.strVal) }
- else if (in.token == INTERPOLATIONID) interpolatedString()
+ else if (in.token == INTERPOLATIONID) interpolatedString(inPattern)
else finish(in.token match {
case CHARLIT => in.charVal
case INTLIT => in.intVal(isNegated).toInt
@@ -612,10 +622,14 @@ object Parsers {
in.nextToken()
while (in.token == STRINGPART) {
segmentBuf += Thicket(
- literal(),
+ literal(inPattern = inPattern),
atPos(in.offset) {
if (in.token == IDENTIFIER)
termIdent()
+ else if (in.token == USCORE && inPattern) {
+ in.nextToken()
+ Ident(nme.WILDCARD)
+ }
else if (in.token == THIS) {
in.nextToken()
This(EmptyTypeIdent)
@@ -624,12 +638,12 @@ object Parsers {
if (inPattern) Block(Nil, inBraces(pattern()))
else expr()
else {
- ctx.error(InterpolatedStringError())
+ ctx.error(InterpolatedStringError(), source atPos Position(in.offset))
EmptyTree
}
})
}
- if (in.token == STRINGLIT) segmentBuf += literal()
+ if (in.token == STRINGLIT) segmentBuf += literal(inPattern = inPattern)
InterpolatedString(interpolator, segmentBuf.toList)
}
@@ -662,13 +676,13 @@ object Parsers {
val t = typ()
findWildcardType(t) match {
case Some(wildcardPos) =>
- syntaxError("unbound wildcard type", wildcardPos)
+ syntaxError(UnboundWildcardType(), wildcardPos)
scalaAny
case None => t
}
}
- /** Type ::= FunArgTypes `=>' Type
+ /** Type ::= [`implicit'] FunArgTypes `=>' Type
* | HkTypeParamClause `->' Type
* | InfixType
* FunArgTypes ::= InfixType
@@ -676,20 +690,26 @@ object Parsers {
*/
def typ(): Tree = {
val start = in.offset
+ val isImplicit = in.token == IMPLICIT
+ if (isImplicit) in.nextToken()
+ def functionRest(params: List[Tree]): Tree =
+ atPos(start, accept(ARROW)) {
+ val t = typ()
+ if (isImplicit) new ImplicitFunction(params, t) else Function(params, t)
+ }
val t =
if (in.token == LPAREN) {
in.nextToken()
if (in.token == RPAREN) {
in.nextToken()
- atPos(start, accept(ARROW)) { Function(Nil, typ()) }
+ functionRest(Nil)
}
else {
openParens.change(LPAREN, 1)
val ts = commaSeparated(funArgType)
openParens.change(LPAREN, -1)
accept(RPAREN)
- if (in.token == ARROW)
- atPos(start, in.skipToken()) { Function(ts, typ()) }
+ if (isImplicit || in.token == ARROW) functionRest(ts)
else {
for (t <- ts)
if (t.isInstanceOf[ByNameTypeTree])
@@ -709,8 +729,8 @@ object Parsers {
else infixType()
in.token match {
- case ARROW => atPos(start, in.skipToken()) { Function(List(t), typ()) }
- case FORSOME => syntaxError("existential types no longer supported; use a wildcard type or dependent type instead"); t
+ case ARROW => functionRest(t :: Nil)
+ case FORSOME => syntaxError(ExistentialTypesNoLongerSupported()); t
case _ => t
}
}
@@ -728,7 +748,7 @@ object Parsers {
def refinedTypeRest(t: Tree): Tree = {
newLineOptWhenFollowedBy(LBRACE)
- if (in.token == LBRACE) refinedTypeRest(atPos(t.pos.start) { RefinedTypeTree(t, refinement()) })
+ if (in.token == LBRACE) refinedTypeRest(atPos(startOffset(t)) { RefinedTypeTree(t, refinement()) })
else t
}
@@ -749,11 +769,11 @@ object Parsers {
def annotType(): Tree = annotTypeRest(simpleType())
def annotTypeRest(t: Tree): Tree =
- if (in.token == AT) annotTypeRest(atPos(t.pos.start) { Annotated(t, annot()) })
+ if (in.token == AT) annotTypeRest(atPos(startOffset(t)) { Annotated(t, annot()) })
else t
/** SimpleType ::= SimpleType TypeArgs
- * | SimpleType `#' Id
+ * | SimpleType `#' id
* | StableId
* | Path `.' type
* | `(' ArgTypes `)'
@@ -763,7 +783,9 @@ object Parsers {
*/
def simpleType(): Tree = simpleTypeRest {
if (in.token == LPAREN)
- atPos(in.offset) { makeTupleOrParens(inParens(argTypes())) }
+ atPos(in.offset) {
+ makeTupleOrParens(inParens(argTypes(namedOK = false, wildOK = true)))
+ }
else if (in.token == LBRACE)
atPos(in.offset) { RefinedTypeTree(EmptyTree, refinement()) }
else if (isSimpleLiteral) { SingletonTypeTree(literal()) }
@@ -780,19 +802,20 @@ object Parsers {
val handleSingletonType: Tree => Tree = t =>
if (in.token == TYPE) {
in.nextToken()
- atPos(t.pos.start) { SingletonTypeTree(t) }
+ atPos(startOffset(t)) { SingletonTypeTree(t) }
} else t
private def simpleTypeRest(t: Tree): Tree = in.token match {
case HASH => simpleTypeRest(typeProjection(t))
- case LBRACKET => simpleTypeRest(atPos(t.pos.start) { AppliedTypeTree(t, typeArgs(namedOK = true)) })
+ case LBRACKET => simpleTypeRest(atPos(startOffset(t)) {
+ AppliedTypeTree(t, typeArgs(namedOK = true, wildOK = true)) })
case _ => t
}
private def typeProjection(t: Tree): Tree = {
accept(HASH)
val id = typeIdent()
- atPos(t.pos.start, id.pos.start) { Select(t, id.name) }
+ atPos(startOffset(t), startOffset(id)) { Select(t, id.name) }
}
/** NamedTypeArg ::= id `=' Type
@@ -806,7 +829,7 @@ object Parsers {
/** ArgTypes ::= Type {`,' Type}
* | NamedTypeArg {`,' NamedTypeArg}
*/
- def argTypes(namedOK: Boolean = false) = {
+ def argTypes(namedOK: Boolean, wildOK: Boolean) = {
def otherArgs(first: Tree, arg: () => Tree): List[Tree] = {
val rest =
if (in.token == COMMA) {
@@ -816,8 +839,9 @@ object Parsers {
else Nil
first :: rest
}
+ def typParser() = if (wildOK) typ() else toplevelTyp()
if (namedOK && in.token == IDENTIFIER)
- typ() match {
+ typParser() match {
case Ident(name) if in.token == EQUALS =>
in.nextToken()
otherArgs(NamedArg(name, typ()), namedTypeArg)
@@ -825,7 +849,7 @@ object Parsers {
if (in.token == EQUALS) println(s"??? $firstArg")
otherArgs(firstArg, typ)
}
- else commaSeparated(typ)
+ else commaSeparated(typParser)
}
/** FunArgType ::= Type | `=>' Type
@@ -846,14 +870,14 @@ object Parsers {
val t = toplevelTyp()
if (isIdent(nme.raw.STAR)) {
in.nextToken()
- atPos(t.pos.start) { PostfixOp(t, nme.raw.STAR) }
+ atPos(startOffset(t)) { PostfixOp(t, nme.raw.STAR) }
} else t
}
/** TypeArgs ::= `[' Type {`,' Type} `]'
* NamedTypeArgs ::= `[' NamedTypeArg {`,' NamedTypeArg} `]'
*/
- def typeArgs(namedOK: Boolean = false): List[Tree] = inBrackets(argTypes(namedOK))
+ def typeArgs(namedOK: Boolean, wildOK: Boolean): List[Tree] = inBrackets(argTypes(namedOK, wildOK))
/** Refinement ::= `{' RefineStatSeq `}'
*/
@@ -932,14 +956,14 @@ object Parsers {
}
}
- /** Expr ::= FunParams `=>' Expr
+ /** Expr ::= [`implicit'] FunParams `=>' Expr
* | Expr1
* FunParams ::= Bindings
- * | [`implicit'] Id
+ * | id
* | `_'
* ExprInParens ::= PostfixExpr `:' Type
* | Expr
- * BlockResult ::= (FunParams | [`implicit'] Id `:' InfixType) => Block
+ * BlockResult ::= [`implicit'] FunParams `=>' Block
* | Expr1
* Expr1 ::= `if' `(' Expr `)' {nl} Expr [[semi] else Expr]
* | `if' Expr `then' Expr [[semi] else Expr]
@@ -951,12 +975,12 @@ object Parsers {
* | `throw' Expr
* | `return' [Expr]
* | ForExpr
- * | [SimpleExpr `.'] Id `=' Expr
+ * | [SimpleExpr `.'] id `=' Expr
* | SimpleExpr1 ArgumentExprs `=' Expr
* | PostfixExpr [Ascription]
* | PostfixExpr `match' `{' CaseClauses `}'
* Bindings ::= `(' [Binding {`,' Binding}] `)'
- * Binding ::= (Id | `_') [`:' Type]
+ * Binding ::= (id | `_') [`:' Type]
* Ascription ::= `:' CompoundType
* | `:' Annotation {Annotation}
* | `:' `_' `*'
@@ -966,22 +990,27 @@ object Parsers {
def expr(): Tree = expr(Location.ElseWhere)
def expr(location: Location.Value): Tree = {
- val saved = placeholderParams
- placeholderParams = Nil
- val t = expr1(location)
- if (in.token == ARROW) {
- placeholderParams = saved
- closureRest(t.pos.start, location, convertToParams(t))
- }
- else if (isWildcard(t)) {
- placeholderParams = placeholderParams ::: saved
- t
+ val start = in.offset
+ if (in.token == IMPLICIT)
+ implicitClosure(start, location, implicitMods())
+ else {
+ val saved = placeholderParams
+ placeholderParams = Nil
+ val t = expr1(location)
+ if (in.token == ARROW) {
+ placeholderParams = saved
+ closureRest(start, location, convertToParams(t))
+ }
+ else if (isWildcard(t)) {
+ placeholderParams = placeholderParams ::: saved
+ t
+ }
+ else
+ try
+ if (placeholderParams.isEmpty) t
+ else new WildcardFunction(placeholderParams.reverse, t)
+ finally placeholderParams = saved
}
- else
- try
- if (placeholderParams.isEmpty) t
- else new WildcardFunction(placeholderParams.reverse, t)
- finally placeholderParams = saved
}
def expr1(location: Location.Value = Location.ElseWhere): Tree = in.token match {
@@ -1025,7 +1054,7 @@ object Parsers {
assert(handlerStart != -1)
syntaxError(
new EmptyCatchBlock(body),
- Position(handlerStart, handler.pos.end)
+ Position(handlerStart, endOffset(handler))
)
case _ =>
}
@@ -1035,7 +1064,7 @@ object Parsers {
else {
if (handler.isEmpty) warning(
EmptyCatchAndFinallyBlock(body),
- source atPos Position(tryOffset, body.pos.end)
+ source atPos Position(tryOffset, endOffset(body))
)
EmptyTree
}
@@ -1047,8 +1076,6 @@ object Parsers {
atPos(in.skipToken()) { Return(if (isExprIntro) expr() else EmptyTree, EmptyTree) }
case FOR =>
forExpr()
- case IMPLICIT =>
- implicitClosure(in.skipToken(), location)
case _ =>
expr1Rest(postfixExpr(), location)
}
@@ -1057,21 +1084,21 @@ object Parsers {
case EQUALS =>
t match {
case Ident(_) | Select(_, _) | Apply(_, _) =>
- atPos(t.pos.start, in.skipToken()) { Assign(t, expr()) }
+ atPos(startOffset(t), in.skipToken()) { Assign(t, expr()) }
case _ =>
t
}
case COLON =>
ascription(t, location)
case MATCH =>
- atPos(t.pos.start, in.skipToken()) {
+ atPos(startOffset(t), in.skipToken()) {
inBraces(Match(t, caseClauses()))
}
case _ =>
t
}
- def ascription(t: Tree, location: Location.Value) = atPos(t.pos.start, in.skipToken()) {
+ def ascription(t: Tree, location: Location.Value) = atPos(startOffset(t), in.skipToken()) {
in.token match {
case USCORE =>
val uscoreStart = in.skipToken()
@@ -1096,20 +1123,53 @@ object Parsers {
}
}
- /** Expr ::= implicit Id `=>' Expr
- * BlockResult ::= implicit Id [`:' InfixType] `=>' Block
+ /** FunParams ::= Bindings
+ * | id
+ * | `_'
+ * Bindings ::= `(' [Binding {`,' Binding}] `)'
*/
- def implicitClosure(start: Int, location: Location.Value, implicitMod: Option[Mod] = None): Tree = {
- var mods = atPos(start) { Modifiers(Implicit) }
- if (implicitMod.nonEmpty) mods = mods.withAddedMod(implicitMod.get)
- val id = termIdent()
- val paramExpr =
- if (location == Location.InBlock && in.token == COLON)
- atPos(id.pos.start, in.skipToken()) { Typed(id, infixType()) }
- else
- id
- closureRest(start, location, convertToParam(paramExpr, mods) :: Nil)
- }
+ def funParams(mods: Modifiers, location: Location.Value): List[Tree] =
+ if (in.token == LPAREN)
+ inParens(if (in.token == RPAREN) Nil else commaSeparated(() => binding(mods)))
+ else {
+ val start = in.offset
+ val name = bindingName()
+ val t =
+ if (in.token == COLON && location == Location.InBlock) {
+ if (false) // Don't error yet, as the alternative syntax "implicit (x: T) => ... "
+ // is not supported by Scala2.x
+ migrationWarningOrError(s"This syntax is no longer supported; parameter needs to be enclosed in (...)")
+
+ in.nextToken()
+ val t = infixType()
+
+ if (false && in.isScala2Mode) {
+ patch(source, Position(start), "(")
+ patch(source, Position(in.lastOffset), ")")
+ }
+ t
+ }
+ else TypeTree()
+ (atPos(start) { makeParameter(name, t, mods) }) :: Nil
+ }
+
+ /** Binding ::= (id | `_') [`:' Type]
+ */
+ def binding(mods: Modifiers): Tree =
+ atPos(in.offset) { makeParameter(bindingName(), typedOpt(), mods) }
+
+ def bindingName(): TermName =
+ if (in.token == USCORE) {
+ in.nextToken()
+ ctx.freshName(nme.USCORE_PARAM_PREFIX).toTermName
+ }
+ else ident()
+
+ /** Expr ::= implicit id `=>' Expr
+ * BlockResult ::= implicit id [`:' InfixType] `=>' Block // Scala2 only
+ */
+ def implicitClosure(start: Int, location: Location.Value, implicitMods: Modifiers): Tree =
+ closureRest(start, location, funParams(implicitMods, location))
def closureRest(start: Int, location: Location.Value, params: List[Tree]): Tree =
atPos(start, in.offset) {
@@ -1117,9 +1177,9 @@ object Parsers {
Function(params, if (location == Location.InBlock) block() else expr())
}
- /** PostfixExpr ::= InfixExpr [Id [nl]]
+ /** PostfixExpr ::= InfixExpr [id [nl]]
* InfixExpr ::= PrefixExpr
- * | InfixExpr Id [nl] InfixExpr
+ * | InfixExpr id [nl] InfixExpr
*/
def postfixExpr(): Tree =
infixOps(prefixExpr(), canStartExpressionTokens, prefixExpr, maybePostfix = true)
@@ -1144,7 +1204,7 @@ object Parsers {
* | xmlLiteral
* | Path
* | `(' [ExprsInParens] `)'
- * | SimpleExpr `.' Id
+ * | SimpleExpr `.' id
* | SimpleExpr (TypeArgs | NamedTypeArgs)
* | SimpleExpr1 ArgumentExprs
*/
@@ -1194,13 +1254,13 @@ object Parsers {
in.nextToken()
simpleExprRest(selector(t), canApply = true)
case LBRACKET =>
- val tapp = atPos(t.pos.start, in.offset) { TypeApply(t, typeArgs(namedOK = true)) }
+ val tapp = atPos(startOffset(t), in.offset) { TypeApply(t, typeArgs(namedOK = true, wildOK = false)) }
simpleExprRest(tapp, canApply = true)
case LPAREN | LBRACE if canApply =>
- val app = atPos(t.pos.start, in.offset) { Apply(t, argumentExprs()) }
+ val app = atPos(startOffset(t), in.offset) { Apply(t, argumentExprs()) }
simpleExprRest(app, canApply = true)
case USCORE =>
- atPos(t.pos.start, in.skipToken()) { PostfixOp(t, nme.WILDCARD) }
+ atPos(startOffset(t), in.skipToken()) { PostfixOp(t, nme.WILDCARD) }
case _ =>
t
}
@@ -1284,7 +1344,7 @@ object Parsers {
if (in.token == IF) guard()
else {
val pat = pattern1()
- if (in.token == EQUALS) atPos(pat.pos.start, in.skipToken()) { GenAlias(pat, expr()) }
+ if (in.token == EQUALS) atPos(startOffset(pat), in.skipToken()) { GenAlias(pat, expr()) }
else generatorRest(pat)
}
@@ -1293,7 +1353,7 @@ object Parsers {
def generator(): Tree = generatorRest(pattern1())
def generatorRest(pat: Tree) =
- atPos(pat.pos.start, accept(LARROW)) { GenFrom(pat, expr()) }
+ atPos(startOffset(pat), accept(LARROW)) { GenFrom(pat, expr()) }
/** ForExpr ::= `for' (`(' Enumerators `)' | `{' Enumerators `}')
* {nl} [`yield'] Expr
@@ -1357,7 +1417,7 @@ object Parsers {
val pattern = () => {
val pat = pattern1()
if (isIdent(nme.raw.BAR))
- atPos(pat.pos.start) { Alternative(pat :: patternAlts()) }
+ atPos(startOffset(pat)) { Alternative(pat :: patternAlts()) }
else pat
}
@@ -1383,20 +1443,20 @@ object Parsers {
// compatibility for Scala2 `x @ _*` syntax
infixPattern() match {
case pt @ Ident(tpnme.WILDCARD_STAR) =>
- migrationWarningOrError("The syntax `x @ _*' is no longer supported; use `x : _*' instead", p.pos.start)
- atPos(p.pos.start, offset) { Typed(p, pt) }
+ migrationWarningOrError("The syntax `x @ _*' is no longer supported; use `x : _*' instead", startOffset(p))
+ atPos(startOffset(p), offset) { Typed(p, pt) }
case p =>
- atPos(p.pos.start, offset) { Bind(name, p) }
+ atPos(startOffset(p), offset) { Bind(name, p) }
}
case p @ Ident(tpnme.WILDCARD_STAR) =>
// compatibility for Scala2 `_*` syntax
- migrationWarningOrError("The syntax `_*' is no longer supported; use `x : _*' instead", p.pos.start)
- atPos(p.pos.start) { Typed(Ident(nme.WILDCARD), p) }
+ migrationWarningOrError("The syntax `_*' is no longer supported; use `x : _*' instead", startOffset(p))
+ atPos(startOffset(p)) { Typed(Ident(nme.WILDCARD), p) }
case p =>
p
}
- /** InfixPattern ::= SimplePattern {Id [nl] SimplePattern}
+ /** InfixPattern ::= SimplePattern {id [nl] SimplePattern}
*/
def infixPattern(): Tree =
infixOps(simplePattern(), canStartExpressionTokens, simplePattern, notAnOperator = nme.raw.BAR)
@@ -1408,14 +1468,14 @@ object Parsers {
* | SimplePattern1 [TypeArgs] [ArgumentPatterns]
* SimplePattern1 ::= Path
* | `{' Block `}'
- * | SimplePattern1 `.' Id
- * PatVar ::= Id
+ * | SimplePattern1 `.' id
+ * PatVar ::= id
* | `_'
*/
val simplePattern = () => in.token match {
case IDENTIFIER | BACKQUOTED_IDENT | THIS =>
path(thisOK = true) match {
- case id @ Ident(nme.raw.MINUS) if isNumericLit => literal(id.pos.start)
+ case id @ Ident(nme.raw.MINUS) if isNumericLit => literal(startOffset(id))
case t => simplePatternRest(t)
}
case USCORE =>
@@ -1435,7 +1495,7 @@ object Parsers {
case XMLSTART =>
xmlLiteralPattern()
case _ =>
- if (isLiteral) literal()
+ if (isLiteral) literal(inPattern = true)
else {
syntaxErrorOrIncomplete(IllegalStartOfSimplePattern())
errorTermTree
@@ -1445,9 +1505,9 @@ object Parsers {
def simplePatternRest(t: Tree): Tree = {
var p = t
if (in.token == LBRACKET)
- p = atPos(t.pos.start, in.offset) { TypeApply(p, typeArgs()) }
+ p = atPos(startOffset(t), in.offset) { TypeApply(p, typeArgs(namedOK = false, wildOK = false)) }
if (in.token == LPAREN)
- p = atPos(t.pos.start, in.offset) { Apply(p, argumentPatterns()) }
+ p = atPos(startOffset(t), in.offset) { Apply(p, argumentPatterns()) }
p
}
@@ -1470,7 +1530,7 @@ object Parsers {
private def modOfToken(tok: Int): Mod = tok match {
case ABSTRACT => Mod.Abstract()
case FINAL => Mod.Final()
- case IMPLICIT => Mod.Implicit(ImplicitCommon)
+ case IMPLICIT => Mod.Implicit()
case INLINE => Mod.Inline()
case LAZY => Mod.Lazy()
case OVERRIDE => Mod.Override()
@@ -1526,7 +1586,7 @@ object Parsers {
def addMod(mods: Modifiers, mod: Mod): Modifiers =
addFlag(mods, mod.flags).withAddedMod(mod)
- /** AccessQualifier ::= "[" (Id | this) "]"
+ /** AccessQualifier ::= "[" (id | this) "]"
*/
def accessQualifierOpt(mods: Modifiers): Modifiers =
if (in.token == LBRACKET) {
@@ -1563,6 +1623,9 @@ object Parsers {
normalize(loop(start))
}
+ def implicitMods(): Modifiers =
+ addMod(EmptyModifiers, atPos(accept(IMPLICIT)) { Mod.Implicit() })
+
/** Wrap annotation or constructor in New(...).<init> */
def wrapNew(tpt: Tree) = Select(New(tpt), nme.CONSTRUCTOR)
@@ -1573,7 +1636,8 @@ object Parsers {
case Select(qual, name) => cpy.Select(tree)(adjustStart(start)(qual), name)
case _ => tree
}
- if (start < tree1.pos.start) tree1.withPos(tree1.pos.withStart(start))
+ if (tree1.pos.exists && start < tree1.pos.start)
+ tree1.withPos(tree1.pos.withStart(start))
else tree1
}
@@ -1601,16 +1665,16 @@ object Parsers {
/** ClsTypeParamClause::= `[' ClsTypeParam {`,' ClsTypeParam} `]'
* ClsTypeParam ::= {Annotation} [{Modifier} type] [`+' | `-']
- * Id [HkTypeParamClause] TypeParamBounds
+ * id [HkTypeParamClause] TypeParamBounds
*
* DefTypeParamClause::= `[' DefTypeParam {`,' DefTypeParam} `]'
- * DefTypeParam ::= {Annotation} Id [HkTypeParamClause] TypeParamBounds
+ * DefTypeParam ::= {Annotation} id [HkTypeParamClause] TypeParamBounds
*
* TypTypeParamCaluse::= `[' TypTypeParam {`,' TypTypeParam} `]'
- * TypTypeParam ::= {Annotation} Id [HkTypePamClause] TypeBounds
+ * TypTypeParam ::= {Annotation} id [HkTypePamClause] TypeBounds
*
* HkTypeParamClause ::= `[' HkTypeParam {`,' HkTypeParam} `]'
- * HkTypeParam ::= {Annotation} ['+' | `-'] (Id[HkTypePamClause] | _') TypeBounds
+ * HkTypeParam ::= {Annotation} ['+' | `-'] (id [HkTypePamClause] | _') TypeBounds
*/
def typeParamClause(ownerKind: ParamOwner.Value): List[TypeDef] = inBrackets {
def typeParam(): TypeDef = {
@@ -1667,9 +1731,9 @@ object Parsers {
* Param ::= id `:' ParamType [`=' Expr]
*/
def paramClauses(owner: Name, ofCaseClass: Boolean = false): List[List[ValDef]] = {
- var implicitMod: Mod = null
- var firstClauseOfCaseClass = ofCaseClass
+ var imods: Modifiers = EmptyModifiers
var implicitOffset = -1 // use once
+ var firstClauseOfCaseClass = ofCaseClass
def param(): ValDef = {
val start = in.offset
var mods = annotsAsMods()
@@ -1704,7 +1768,7 @@ object Parsers {
if (in.token == ARROW) {
if (owner.isTypeName && !(mods is Local))
syntaxError(s"${if (mods is Mutable) "`var'" else "`val'"} parameters may not be call-by-name")
- else if (implicitMod != null)
+ else if (imods.hasFlags)
syntaxError("implicit parameters may not be call-by-name")
}
paramType()
@@ -1716,7 +1780,7 @@ object Parsers {
mods = mods.withPos(mods.pos.union(Position(implicitOffset, implicitOffset)))
implicitOffset = -1
}
- if (implicitMod != null) mods = addMod(mods, implicitMod)
+ for (imod <- imods.mods) mods = addMod(mods, imod)
ValDef(name, tpt, default).withMods(mods)
}
}
@@ -1725,7 +1789,7 @@ object Parsers {
else {
if (in.token == IMPLICIT) {
implicitOffset = in.offset
- implicitMod = atPos(in.skipToken()) { Mod.Implicit(Implicit) }
+ imods = implicitMods()
}
commaSeparated(param)
}
@@ -1735,7 +1799,7 @@ object Parsers {
if (in.token == LPAREN)
paramClause() :: {
firstClauseOfCaseClass = false
- if (implicitMod == null) clauses() else Nil
+ if (imods.hasFlags) Nil else clauses()
}
else Nil
}
@@ -1765,13 +1829,13 @@ object Parsers {
}
}
- /** ImportExpr ::= StableId `.' (Id | `_' | ImportSelectors)
+ /** ImportExpr ::= StableId `.' (id | `_' | ImportSelectors)
*/
val importExpr = () => path(thisOK = false, handleImport) match {
case imp: Import =>
imp
case sel @ Select(qual, name) =>
- val selector = atPos(sel.pos.point) { Ident(name) }
+ val selector = atPos(pointOffset(sel)) { Ident(name) }
cpy.Import(sel)(qual, selector :: Nil)
case t =>
accept(DOT)
@@ -1799,12 +1863,12 @@ object Parsers {
}
}
- /** ImportSelector ::= Id [`=>' Id | `=>' `_']
+ /** ImportSelector ::= id [`=>' id | `=>' `_']
*/
def importSelector(): Tree = {
val from = termIdentOrWildcard()
if (from.name != nme.WILDCARD && in.token == ARROW)
- atPos(from.pos.start, in.skipToken()) {
+ atPos(startOffset(from), in.skipToken()) {
Thicket(from, termIdentOrWildcard())
}
else from
@@ -1844,9 +1908,9 @@ object Parsers {
}
/** PatDef ::= Pattern2 {`,' Pattern2} [`:' Type] `=' Expr
- * VarDef ::= PatDef | Id {`,' Id} `:' Type `=' `_'
- * ValDcl ::= Id {`,' Id} `:' Type
- * VarDcl ::= Id {`,' Id} `:' Type
+ * VarDef ::= PatDef | id {`,' id} `:' Type `=' `_'
+ * ValDcl ::= id {`,' id} `:' Type
+ * VarDcl ::= id {`,' id} `:' Type
*/
def patDefOrDcl(start: Offset, mods: Modifiers, docstring: Option[Comment] = None): Tree = atPos(start, nameStart) {
val lhs = commaSeparated(pattern2)
@@ -1887,6 +1951,7 @@ object Parsers {
if (in.token == THIS) {
in.nextToken()
val vparamss = paramClauses(nme.CONSTRUCTOR)
+ if (in.isScala2Mode) newLineOptWhenFollowedBy(LBRACE)
val rhs = {
if (!(in.token == LBRACE && scala2ProcedureSyntax(""))) accept(EQUALS)
atPos(in.offset) { constrExpr() }
@@ -1898,6 +1963,7 @@ object Parsers {
val tparams = typeParamClauseOpt(ParamOwner.Def)
val vparamss = paramClauses(name)
var tpt = fromWithinReturnType(typedOpt())
+ if (in.isScala2Mode) newLineOptWhenFollowedBy(LBRACE)
val rhs =
if (in.token == EQUALS) {
in.nextToken()
@@ -1946,8 +2012,8 @@ object Parsers {
Block(stats, Literal(Constant(())))
}
- /** TypeDef ::= type Id [TypeParamClause] `=' Type
- * TypeDcl ::= type Id [TypeParamClause] TypeBounds
+ /** TypeDef ::= type id [TypeParamClause] `=' Type
+ * TypeDcl ::= type id [TypeParamClause] TypeBounds
*/
def typeDefOrDcl(start: Offset, mods: Modifiers, docstring: Option[Comment] = None): Tree = {
newLinesOpt()
@@ -1989,7 +2055,7 @@ object Parsers {
}
}
- /** ClassDef ::= Id [ClsTypeParamClause]
+ /** ClassDef ::= id [ClsTypeParamClause]
* [ConstrMods] ClsParamClauses TemplateOpt
*/
def classDef(start: Offset, mods: Modifiers, docstring: Option[Comment]): TypeDef = atPos(start, nameStart) {
@@ -2017,7 +2083,7 @@ object Parsers {
mods
}
- /** ObjectDef ::= Id TemplateOpt
+ /** ObjectDef ::= id TemplateOpt
*/
def objectDef(start: Offset, mods: Modifiers, docstring: Option[Comment] = None): ModuleDef = atPos(start, nameStart) {
val name = ident()
@@ -2085,7 +2151,7 @@ object Parsers {
/** Create a tree representing a packaging */
def makePackaging(start: Int, pkg: Tree, stats: List[Tree]): PackageDef = pkg match {
- case x: RefTree => atPos(start, pkg.pos.point)(PackageDef(x, stats))
+ case x: RefTree => atPos(start, pointOffset(pkg))(PackageDef(x, stats))
}
/** Packaging ::= package QualId [nl] `{' TopStatSeq `}'
@@ -2198,9 +2264,9 @@ object Parsers {
stats.toList
}
- def localDef(start: Int, implicitFlag: FlagSet, implicitMod: Option[Mod] = None): Tree = {
- var mods = addFlag(defAnnotsMods(localModifierTokens), implicitFlag)
- if (implicitMod.nonEmpty) mods = mods.withAddedMod(implicitMod.get)
+ def localDef(start: Int, implicitMods: Modifiers = EmptyModifiers): Tree = {
+ var mods = defAnnotsMods(localModifierTokens)
+ for (imod <- implicitMods.mods) mods = addMod(mods, imod)
defOrDcl(start, mods)
}
@@ -2223,11 +2289,11 @@ object Parsers {
else if (isDefIntro(localModifierTokens))
if (in.token == IMPLICIT) {
val start = in.offset
- val mod = atPos(in.skipToken()) { Mod.Implicit(ImplicitCommon) }
- if (isIdent) stats += implicitClosure(start, Location.InBlock, Some(mod))
- else stats += localDef(start, ImplicitCommon, Some(mod))
+ val imods = implicitMods()
+ if (isBindingIntro) stats += implicitClosure(start, Location.InBlock, imods)
+ else stats += localDef(start, imods)
} else {
- stats += localDef(in.offset, EmptyFlags)
+ stats += localDef(in.offset)
}
else if (!isStatSep && (in.token != CASE)) {
exitOnError = mustStartStat
diff --git a/compiler/src/dotty/tools/dotc/parsing/Scanners.scala b/compiler/src/dotty/tools/dotc/parsing/Scanners.scala
index 60003d098..101be167e 100644
--- a/compiler/src/dotty/tools/dotc/parsing/Scanners.scala
+++ b/compiler/src/dotty/tools/dotc/parsing/Scanners.scala
@@ -758,7 +758,7 @@ object Scanners {
finishStringPart()
nextRawChar()
next.token = LBRACE
- } else if (Character.isUnicodeIdentifierStart(ch)) {
+ } else if (Character.isUnicodeIdentifierStart(ch) || ch == '_') {
finishStringPart()
do {
putChar(ch)
diff --git a/compiler/src/dotty/tools/dotc/parsing/Tokens.scala b/compiler/src/dotty/tools/dotc/parsing/Tokens.scala
index 5324207db..280832ef3 100644
--- a/compiler/src/dotty/tools/dotc/parsing/Tokens.scala
+++ b/compiler/src/dotty/tools/dotc/parsing/Tokens.scala
@@ -209,6 +209,8 @@ object Tokens extends TokensCommon {
final val canStartTypeTokens = literalTokens | identifierTokens | BitSet(
THIS, SUPER, USCORE, LPAREN, AT)
+ final val canStartBindingTokens = identifierTokens | BitSet(USCORE, LPAREN)
+
final val templateIntroTokens = BitSet(CLASS, TRAIT, OBJECT, CASECLASS, CASEOBJECT)
final val dclIntroTokens = BitSet(DEF, VAL, VAR, TYPE)
diff --git a/compiler/src/dotty/tools/dotc/printing/Formatting.scala b/compiler/src/dotty/tools/dotc/printing/Formatting.scala
index b321d3736..05f1af9d7 100644
--- a/compiler/src/dotty/tools/dotc/printing/Formatting.scala
+++ b/compiler/src/dotty/tools/dotc/printing/Formatting.scala
@@ -96,7 +96,10 @@ object Formatting {
case tpe: Type =>
tpe.exists && !tpe.isErroneous
case sym: Symbol if sym.isCompleted =>
- sym.info != ErrorType && sym.info != TypeAlias(ErrorType) && sym.info.exists
+ sym.info match {
+ case _: ErrorType | TypeAlias(_: ErrorType) | NoType => false
+ case _ => true
+ }
case _ => true
}
diff --git a/compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala b/compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala
index 15c382bb0..61f23c214 100644
--- a/compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala
+++ b/compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala
@@ -154,7 +154,7 @@ class PlainPrinter(_ctx: Context) extends Printer {
changePrec(AndPrec) { toText(tp1) ~ " & " ~ toText(tp2) }
case OrType(tp1, tp2) =>
changePrec(OrPrec) { toText(tp1) ~ " | " ~ toText(tp2) }
- case ErrorType =>
+ case _: ErrorType =>
"<error>"
case tp: WildcardType =>
if (tp.optBounds.exists) "(?" ~ toTextRHS(tp.bounds) ~ ")" else "?"
diff --git a/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala b/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala
index 00627fc28..3085ad8fd 100644
--- a/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala
+++ b/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala
@@ -113,20 +113,21 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
override def toText(tp: Type): Text = controlled {
def toTextTuple(args: List[Type]): Text =
"(" ~ Text(args.map(argText), ", ") ~ ")"
- def toTextFunction(args: List[Type]): Text =
+ def toTextFunction(args: List[Type], isImplicit: Boolean): Text =
changePrec(GlobalPrec) {
val argStr: Text =
if (args.length == 2 && !defn.isTupleType(args.head))
atPrec(InfixPrec) { argText(args.head) }
else
toTextTuple(args.init)
- argStr ~ " => " ~ argText(args.last)
+ ("implicit " provided isImplicit) ~ argStr ~ " => " ~ argText(args.last)
}
homogenize(tp) match {
case AppliedType(tycon, args) =>
val cls = tycon.typeSymbol
if (tycon.isRepeatedParam) return toTextLocal(args.head) ~ "*"
- if (defn.isFunctionClass(cls)) return toTextFunction(args)
+ if (defn.isFunctionClass(cls)) return toTextFunction(args, isImplicit = false)
+ if (defn.isImplicitFunctionClass(cls)) return toTextFunction(args, isImplicit = true)
if (defn.isTupleClass(cls)) return toTextTuple(args)
return (toTextLocal(tycon) ~ "[" ~ Text(args map argText, ", ") ~ "]").close
case tp: TypeRef =>
@@ -614,14 +615,12 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
(sym.allOverriddenSymbols exists (_ is TypeParam))
override def toText(sym: Symbol): Text = {
- if (sym.isImport) {
- def importString(tree: untpd.Tree) = s"import ${tree.show}"
+ if (sym.isImport)
sym.infoOrCompleter match {
- case info: Namer#Completer => return importString(info.original)
- case info: ImportType => return importString(info.expr)
+ case info: Namer#Completer => return info.original.show
+ case info: ImportType => return s"import $info.expr.show"
case _ =>
}
- }
if (sym.is(ModuleClass))
kindString(sym) ~~ (nameString(sym.name.stripModuleClassSuffix) + idString(sym))
else
diff --git a/compiler/src/dotty/tools/dotc/repl/CompilingInterpreter.scala b/compiler/src/dotty/tools/dotc/repl/CompilingInterpreter.scala
index 5b3669d5e..65c64f708 100644
--- a/compiler/src/dotty/tools/dotc/repl/CompilingInterpreter.scala
+++ b/compiler/src/dotty/tools/dotc/repl/CompilingInterpreter.scala
@@ -6,7 +6,7 @@ import java.io.{
File, PrintWriter, PrintStream, StringWriter, Writer, OutputStream,
ByteArrayOutputStream => ByteOutputStream
}
-import java.lang.{Class, ClassLoader}
+import java.lang.{Class, ClassLoader, Thread, System, StringBuffer}
import java.net.{URL, URLClassLoader}
import scala.collection.immutable.ListSet
@@ -443,7 +443,10 @@ class CompilingInterpreter(
}
// the types are all =>T; remove the =>
- val cleanedType = rawType.widenExpr
+ val cleanedType = rawType.widenExpr match {
+ case tp: MethodType => tp.resultType
+ case tp => tp
+ }
map + (name ->
ctx.atPhase(ctx.typerPhase.next) { implicit ctx =>
@@ -680,15 +683,49 @@ class CompilingInterpreter(
code.print(resultExtractors.mkString(""))
}
+ private val ListReg = """^.*List\[(\w+)\]$""".r
+ private val MapReg = """^.*Map\[(\w+),[ ]*(\w+)\]$""".r
+ private val LitReg = """^.*\((.+)\)$""".r
+
private def resultExtractor(req: Request, varName: Name): String = {
val prettyName = varName.decode
- val varType = string2code(req.typeOf(varName))
+ // FIXME: `varType` is prettified to abbreviate common types where
+ // appropriate, and to also prettify literal types
+ //
+ // This should be rewritten to use the actual types once we have a
+ // semantic representation available to the REPL
+ val varType = string2code(req.typeOf(varName)) match {
+ // Extract List's paremeter from full path
+ case ListReg(param) => s"List[$param]"
+ // Extract Map's paremeters from full path
+ case MapReg(k, v) => s"Map[$k, $v]"
+ // Extract literal type from literal type representation. Example:
+ //
+ // ```
+ // scala> val x: 42 = 42
+ // val x: Int(42) = 42
+ // scala> val y: "hello" = "hello"
+ // val y: String("hello") = "hello"
+ // ```
+ case LitReg(lit) => lit
+ // When the type is a singleton value like None, don't show `None$`
+ // instead show `None.type`.
+ case x if x.lastOption == Some('$') => x.init + ".type"
+ case x => x
+ }
val fullPath = req.fullPath(varName)
- s""" + "$prettyName: $varType = " + {
+ val varOrVal = statement match {
+ case v: ValDef if v.mods is Flags.Mutable => "var"
+ case _ => "val"
+ }
+
+ s""" + "$varOrVal $prettyName: $varType = " + {
| if ($fullPath.asInstanceOf[AnyRef] != null) {
- | (if ($fullPath.toString().contains('\\n')) "\\n" else "") +
- | $fullPath.toString() + "\\n"
+ | (if ($fullPath.toString().contains('\\n')) "\\n" else "") + {
+ | import dotty.Show._
+ | $fullPath.show /*toString()*/ + "\\n"
+ | }
| } else {
| "null\\n"
| }
@@ -735,9 +772,30 @@ class CompilingInterpreter(
override def defNames = boundNames
override def resultExtractionCode(req: Request, code: PrintWriter): Unit = {
- if (!defDef.mods.is(Flags.AccessFlags))
- code.print("+\"" + string2code(defDef.name.toString) + ": " +
- string2code(req.typeOf(defDef.name)) + "\\n\"")
+ /** TODO: This is the result of the state of the REPL - this would be
+ * entirely unnecessary with a better structure where we could just
+ * use the type printer
+ *
+ * @see `def findTypes` for an explanation of what should be done
+ */
+ if (!defDef.mods.is(Flags.AccessFlags)) {
+ // Take the DefDef and remove the `rhs` and ascribed type `tpt`
+ val copy = ast.untpd.cpy.DefDef(defDef)(
+ rhs = EmptyTree,
+ tpt = TypeTree
+ )
+
+ val tpt = defDef.tpt match {
+ // ascribed TypeExpr e.g: `def foo: Int = 5`
+ case Ident(tpt) if defDef.vparamss.isEmpty =>
+ ": " + tpt.show
+ case tpt =>
+ ": " + req.typeOf(defDef.name)
+ }
+ code.print {
+ "+\"" + string2code(copy.show) + tpt + "\\n\""
+ }
+ }
}
}
diff --git a/compiler/src/dotty/tools/dotc/repl/InterpreterLoop.scala b/compiler/src/dotty/tools/dotc/repl/InterpreterLoop.scala
index b3ac41c55..cfe8d892d 100644
--- a/compiler/src/dotty/tools/dotc/repl/InterpreterLoop.scala
+++ b/compiler/src/dotty/tools/dotc/repl/InterpreterLoop.scala
@@ -4,7 +4,7 @@ package repl
import java.io.{BufferedReader, File, FileReader, PrintWriter}
import java.io.IOException
-import java.lang.{ClassLoader, System}
+import java.lang.{ClassLoader, System, Thread}
import scala.concurrent.{Future, Await}
import scala.concurrent.duration.Duration
import reporting.Reporter
diff --git a/compiler/src/dotty/tools/dotc/reporting/Reporter.scala b/compiler/src/dotty/tools/dotc/reporting/Reporter.scala
index 8477cfe28..26c1e5ebc 100644
--- a/compiler/src/dotty/tools/dotc/reporting/Reporter.scala
+++ b/compiler/src/dotty/tools/dotc/reporting/Reporter.scala
@@ -286,11 +286,16 @@ abstract class Reporter extends interfaces.ReporterResult {
}
/** Should this diagnostic not be reported at all? */
- def isHidden(m: MessageContainer)(implicit ctx: Context): Boolean = ctx.mode.is(Mode.Printing)
+ def isHidden(m: MessageContainer)(implicit ctx: Context): Boolean =
+ ctx.mode.is(Mode.Printing)
/** Does this reporter contain not yet reported errors or warnings? */
def hasPending: Boolean = false
+ /** If this reporter buffers messages, remove and return all buffered messages. */
+ def removeBufferedMessages(implicit ctx: Context): List[MessageContainer] = Nil
+
/** Issue all error messages in this reporter to next outer one, or make sure they are written. */
- def flush()(implicit ctx: Context): Unit = {}
+ def flush()(implicit ctx: Context): Unit =
+ removeBufferedMessages.foreach(ctx.reporter.report)
}
diff --git a/compiler/src/dotty/tools/dotc/reporting/StoreReporter.scala b/compiler/src/dotty/tools/dotc/reporting/StoreReporter.scala
index 586273c2e..34b109882 100644
--- a/compiler/src/dotty/tools/dotc/reporting/StoreReporter.scala
+++ b/compiler/src/dotty/tools/dotc/reporting/StoreReporter.scala
@@ -36,11 +36,9 @@ class StoreReporter(outer: Reporter) extends Reporter {
}
}
- override def flush()(implicit ctx: Context) =
- if (infos != null) {
- infos.foreach(ctx.reporter.report(_))
- infos = null
- }
+ override def removeBufferedMessages(implicit ctx: Context): List[MessageContainer] =
+ if (infos != null) try infos.toList finally infos = null
+ else Nil
override def errorsReported = hasErrors || outer.errorsReported
}
diff --git a/compiler/src/dotty/tools/dotc/reporting/diagnostic/MessageContainer.scala b/compiler/src/dotty/tools/dotc/reporting/diagnostic/MessageContainer.scala
index 7fd50bfdc..c27644ad9 100644
--- a/compiler/src/dotty/tools/dotc/reporting/diagnostic/MessageContainer.scala
+++ b/compiler/src/dotty/tools/dotc/reporting/diagnostic/MessageContainer.scala
@@ -14,7 +14,7 @@ object MessageContainer {
implicit class MessageContext(val c: Context) extends AnyVal {
def shouldExplain(cont: MessageContainer): Boolean = {
- implicit val ctx: Context = c
+ implicit val ctx = c
cont.contained.explanation match {
case "" => false
case _ => ctx.settings.explain.value
diff --git a/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala b/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala
index 489165e56..89cd2cd8f 100644
--- a/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala
+++ b/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala
@@ -5,8 +5,7 @@ package diagnostic
import dotc.core._
import Contexts.Context, Decorators._, Symbols._, Names._, NameOps._, Types._
-import util.{SourceFile, NoSource}
-import util.{SourcePosition, NoSourcePosition}
+import util.SourcePosition
import config.Settings.Setting
import interfaces.Diagnostic.{ERROR, WARNING, INFO}
import printing.Highlighting._
@@ -224,6 +223,8 @@ object messages {
extends Message(8) {
val kind = "Member Not Found"
+ //println(i"site = $site, decls = ${site.decls}, source = ${site.widen.typeSymbol.sourceFile}") //DEBUG
+
val msg = {
import core.Flags._
val maxDist = 3
@@ -606,7 +607,7 @@ object messages {
|"""
}
- case class WrongNumberOfArgs(fntpe: Type, argKind: String, expectedArgs: List[TypeParamInfo], actual: List[untpd.Tree])(implicit ctx: Context)
+ case class WrongNumberOfTypeArgs(fntpe: Type, expectedArgs: List[TypeParamInfo], actual: List[untpd.Tree])(implicit ctx: Context)
extends Message(22) {
val kind = "Syntax"
@@ -628,7 +629,7 @@ object messages {
}
val msg =
- hl"""|${NoColor(msgPrefix)} ${argKind} arguments for $prettyName$expectedArgString
+ hl"""|${NoColor(msgPrefix)} type arguments for $prettyName$expectedArgString
|expected: $expectedArgString
|actual: $actualArgString""".stripMargin
@@ -899,4 +900,106 @@ object messages {
val msg = hl"trying to define package with same name as `$existing`"
val explanation = ""
}
+
+ case class ExistentialTypesNoLongerSupported()(implicit ctx: Context) extends Message(34) {
+ val kind = "Syntax"
+ val msg =
+ hl"""|Existential types are no longer supported -
+ |use a wildcard or dependent type instead"""
+ val explanation =
+ hl"""|The use of existential types is no longer supported.
+ |
+ |You should use a wildcard or dependent type instead.
+ |
+ |For example:
+ |
+ |Instead of using ${"forSome"} to specify a type variable
+ |
+ |${"List[T forSome { type T }]"}
+ |
+ |Try using a wildcard type variable
+ |
+ |${"List[_]"}
+ |"""
+ }
+
+ case class UnboundWildcardType()(implicit ctx: Context) extends Message(35) {
+ val kind = "Syntax"
+ val msg = "Unbound wildcard type"
+ val explanation =
+ hl"""|The wildcard type syntax (`_`) was used where it could not be bound.
+ |Replace `_` with a non-wildcard type. If the type doesn't matter,
+ |try replacing `_` with ${"Any"}.
+ |
+ |Examples:
+ |
+ |- Parameter lists
+ |
+ | Instead of:
+ | ${"def foo(x: _) = ..."}
+ |
+ | Use ${"Any"} if the type doesn't matter:
+ | ${"def foo(x: Any) = ..."}
+ |
+ |- Type arguments
+ |
+ | Instead of:
+ | ${"val foo = List[_](1, 2)"}
+ |
+ | Use:
+ | ${"val foo = List[Int](1, 2)"}
+ |
+ |- Type bounds
+ |
+ | Instead of:
+ | ${"def foo[T <: _](x: T) = ..."}
+ |
+ | Remove the bounds if the type doesn't matter:
+ | ${"def foo[T](x: T) = ..."}
+ |
+ |- ${"val"} and ${"def"} types
+ |
+ | Instead of:
+ | ${"val foo: _ = 3"}
+ |
+ | Use:
+ | ${"val foo: Int = 3"}
+ |"""
+ }
+
+ case class DanglingThisInPath()(implicit ctx: Context) extends Message(36) {
+ val kind = "Syntax"
+ val msg = hl"""Expected an additional member selection after the keyword ${"this"}"""
+
+ val contextCode =
+ """ trait Outer {
+ | val member: Int
+ | type Member
+ | trait Inner {
+ | ...
+ | }
+ | }"""
+
+ val importCode =
+ """ import Outer.this.member
+ | // ^^^^^^^"""
+
+ val typeCode =
+ """ type T = Outer.this.Member
+ | // ^^^^^^^"""
+
+ val explanation =
+ hl"""|Paths of imports and type selections must not end with the keyword ${"this"}.
+ |
+ |Maybe you forgot to select a member of ${"this"}? As an example, in the
+ |following context:
+ |${contextCode}
+ |
+ |- this is a valid import expression using a path
+ |${importCode}
+ |
+ |- this is a valid type using a path
+ |${typeCode}
+ |"""
+ }
}
diff --git a/compiler/src/dotty/tools/dotc/sbt/ExtractAPI.scala b/compiler/src/dotty/tools/dotc/sbt/ExtractAPI.scala
index bc8528c05..1fffe6841 100644
--- a/compiler/src/dotty/tools/dotc/sbt/ExtractAPI.scala
+++ b/compiler/src/dotty/tools/dotc/sbt/ExtractAPI.scala
@@ -3,7 +3,7 @@ package sbt
import ast.{Trees, tpd}
import core._, core.Decorators._
-import Contexts._, Flags._, Phases._, Trees._, Types._, Symbols._
+import Annotations._, Contexts._, Flags._, Phases._, Trees._, Types._, Symbols._
import Names._, NameOps._, StdNames._
import typer.Inliner
@@ -333,7 +333,7 @@ private class ExtractAPICollector(implicit val ctx: Context) extends ThunkHolder
// TODO: Never dealias. We currently have to dealias because
// sbt main class discovery relies on the signature of the main
// method being fully dealiased. See https://github.com/sbt/zinc/issues/102
- val tp2 = if (!tp.isHK) tp.dealias else tp
+ val tp2 = if (!tp.isHK) tp.dealiasKeepAnnots else tp
tp2 match {
case NoPrefix | NoType =>
Constants.emptyType
@@ -411,9 +411,7 @@ private class ExtractAPICollector(implicit val ctx: Context) extends ThunkHolder
case ConstantType(constant) =>
new api.Constant(apiType(constant.tpe), constant.stringValue)
case AnnotatedType(tpe, annot) =>
- // TODO: Annotation support
- ctx.debuglog(i"sbt-api: skipped annotation in $tp2")
- apiType(tpe)
+ new api.Annotated(apiType(tpe), Array(apiAnnotation(annot)))
case tp: ThisType =>
apiThis(tp.cls)
case tp: ParamType =>
@@ -498,7 +496,6 @@ private class ExtractAPICollector(implicit val ctx: Context) extends ThunkHolder
sym.is(Implicit), sym.is(Lazy), sym.is(Macro), sym.is(SuperAccessor))
}
- // TODO: Support other annotations
def apiAnnotations(s: Symbol): List[api.Annotation] = {
val annots = new mutable.ListBuffer[api.Annotation]
@@ -513,6 +510,27 @@ private class ExtractAPICollector(implicit val ctx: Context) extends ThunkHolder
annots += marker(Inliner.bodyToInline(s).show(printTypesCtx).toString)
}
+ // In the Scala2 ExtractAPI phase we only extract annotations that extend
+ // StaticAnnotation, but in Dotty we currently pickle all annotations so we
+ // extract everything (except inline body annotations which are handled
+ // above).
+ s.annotations.filter(_.symbol != defn.BodyAnnot) foreach { annot =>
+ annots += apiAnnotation(annot)
+ }
+
annots.toList
}
+
+ def apiAnnotation(annot: Annotation): api.Annotation = {
+ // FIXME: To faithfully extract an API we should extract the annotation tree,
+ // sbt instead wants us to extract the annotation type and its arguments,
+ // to do this properly we would need a way to hash trees and types in dotty itself,
+ // instead we pretty-print the annotation tree.
+ // However, we still need to extract the annotation type in the way sbt expect
+ // because sbt uses this information to find tests to run (for example
+ // junit tests are annotated @org.junit.Test).
+ new api.Annotation(
+ apiType(annot.tree.tpe), // Used by sbt to find tests to run
+ Array(new api.AnnotationArgument("FULLTREE", annot.tree.show.toString)))
+ }
}
diff --git a/compiler/src/dotty/tools/dotc/transform/CollectEntryPoints.scala b/compiler/src/dotty/tools/dotc/transform/CollectEntryPoints.scala
index 714255962..331fce46a 100644
--- a/compiler/src/dotty/tools/dotc/transform/CollectEntryPoints.scala
+++ b/compiler/src/dotty/tools/dotc/transform/CollectEntryPoints.scala
@@ -9,7 +9,6 @@ import dotty.tools.dotc.core.Symbols.NoSymbol
import scala.annotation.tailrec
import dotty.tools.dotc.core._
import Symbols._
-import scala.Some
import dotty.tools.dotc.transform.TreeTransforms.{NXTransformations, TransformerInfo, TreeTransform, TreeTransformer}
import dotty.tools.dotc.ast.tpd
import dotty.tools.dotc.core.Contexts.Context
diff --git a/compiler/src/dotty/tools/dotc/transform/ElimByName.scala b/compiler/src/dotty/tools/dotc/transform/ElimByName.scala
index 192227261..2814baf1e 100644
--- a/compiler/src/dotty/tools/dotc/transform/ElimByName.scala
+++ b/compiler/src/dotty/tools/dotc/transform/ElimByName.scala
@@ -71,7 +71,8 @@ class ElimByName extends MiniPhaseTransform with InfoTransformer { thisTransform
def transformArg(arg: Tree, formal: Type): Tree = formal.dealias match {
case formalExpr: ExprType =>
- val argType = arg.tpe.widen
+ var argType = arg.tpe.widenIfUnstable
+ if (defn.isBottomType(argType)) argType = formal.widenExpr
val argFun = arg match {
case Apply(Select(qual, nme.apply), Nil)
if qual.tpe.derivesFrom(defn.FunctionClass(0)) && isPureExpr(qual) =>
diff --git a/compiler/src/dotty/tools/dotc/transform/Erasure.scala b/compiler/src/dotty/tools/dotc/transform/Erasure.scala
index 069176111..71ecb5c65 100644
--- a/compiler/src/dotty/tools/dotc/transform/Erasure.scala
+++ b/compiler/src/dotty/tools/dotc/transform/Erasure.scala
@@ -13,6 +13,7 @@ import core.StdNames._
import core.NameOps._
import core.Decorators._
import core.Constants._
+import core.Definitions._
import typer.NoChecking
import typer.ProtoTypes._
import typer.ErrorReporting._
@@ -36,9 +37,17 @@ class Erasure extends Phase with DenotTransformer { thisTransformer =>
def transform(ref: SingleDenotation)(implicit ctx: Context): SingleDenotation = ref match {
case ref: SymDenotation =>
+ def isCompacted(sym: Symbol) =
+ sym.isAnonymousFunction && {
+ sym.info(ctx.withPhase(ctx.phase.next)) match {
+ case MethodType(nme.ALLARGS :: Nil, _) => true
+ case _ => false
+ }
+ }
+
assert(ctx.phase == this, s"transforming $ref at ${ctx.phase}")
if (ref.symbol eq defn.ObjectClass) {
- // Aftre erasure, all former Any members are now Object members
+ // After erasure, all former Any members are now Object members
val ClassInfo(pre, _, ps, decls, selfInfo) = ref.info
val extendedScope = decls.cloneScope
for (decl <- defn.AnyClass.classInfo.decls)
@@ -59,7 +68,10 @@ class Erasure extends Phase with DenotTransformer { thisTransformer =>
val oldInfo = ref.info
val newInfo = transformInfo(ref.symbol, oldInfo)
val oldFlags = ref.flags
- val newFlags = ref.flags &~ Flags.HasDefaultParams // HasDefaultParams needs to be dropped because overriding might become overloading
+ val newFlags =
+ if (oldSymbol.is(Flags.TermParam) && isCompacted(oldSymbol.owner)) oldFlags &~ Flags.Param
+ else oldFlags &~ Flags.HasDefaultParams // HasDefaultParams needs to be dropped because overriding might become overloading
+
// TODO: define derivedSymDenotation?
if ((oldSymbol eq newSymbol) && (oldOwner eq newOwner) && (oldInfo eq newInfo) && (oldFlags == newFlags)) ref
else {
@@ -82,7 +94,7 @@ class Erasure extends Phase with DenotTransformer { thisTransformer =>
assertErased(tree)
tree match {
case res: tpd.This =>
- assert(!ExplicitOuter.referencesOuter(ctx.owner.enclosingClass, res),
+ assert(!ExplicitOuter.referencesOuter(ctx.owner.lexicallyEnclosingClass, res),
i"Reference to $res from ${ctx.owner.showLocated}")
case ret: tpd.Return =>
// checked only after erasure, as checking before erasure is complicated
@@ -331,8 +343,25 @@ object Erasure extends TypeTestsCasts{
* e.m -> e.[]m if `m` is an array operation other than `clone`.
*/
override def typedSelect(tree: untpd.Select, pt: Type)(implicit ctx: Context): Tree = {
- val sym = tree.symbol
- assert(sym.exists, tree.show)
+
+ def mapOwner(sym: Symbol): Symbol = {
+ def recur(owner: Symbol): Symbol =
+ if ((owner eq defn.AnyClass) || (owner eq defn.AnyValClass)) {
+ assert(sym.isConstructor, s"${sym.showLocated}")
+ defn.ObjectClass
+ } else if (defn.isUnimplementedFunctionClass(owner))
+ defn.FunctionXXLClass
+ else if (defn.isImplicitFunctionClass(owner))
+ recur(defn.FunctionClass(owner.name.functionArity))
+ else
+ owner
+ recur(sym.owner)
+ }
+
+ val origSym = tree.symbol
+ val owner = mapOwner(origSym)
+ val sym = if (owner eq origSym.owner) origSym else owner.info.decl(origSym.name).symbol
+ assert(sym.exists, origSym.showLocated)
def select(qual: Tree, sym: Symbol): Tree = {
val name = tree.typeOpt match {
@@ -366,11 +395,7 @@ object Erasure extends TypeTestsCasts{
def recur(qual: Tree): Tree = {
val qualIsPrimitive = qual.tpe.widen.isPrimitiveValueType
val symIsPrimitive = sym.owner.isPrimitiveValueClass
- if ((sym.owner eq defn.AnyClass) || (sym.owner eq defn.AnyValClass)) {
- assert(sym.isConstructor, s"${sym.showLocated}")
- select(qual, defn.ObjectClass.info.decl(sym.name).symbol)
- }
- else if (qualIsPrimitive && !symIsPrimitive || qual.tpe.widenDealias.isErasedValueType)
+ if (qualIsPrimitive && !symIsPrimitive || qual.tpe.widenDealias.isErasedValueType)
recur(box(qual))
else if (!qualIsPrimitive && symIsPrimitive)
recur(unbox(qual, sym.owner.typeRef))
@@ -389,7 +414,7 @@ object Erasure extends TypeTestsCasts{
}
override def typedThis(tree: untpd.This)(implicit ctx: Context): Tree =
- if (tree.symbol == ctx.owner.enclosingClass || tree.symbol.isStaticOwner) promote(tree)
+ if (tree.symbol == ctx.owner.lexicallyEnclosingClass || tree.symbol.isStaticOwner) promote(tree)
else {
ctx.log(i"computing outer path from ${ctx.owner.ownersIterator.toList}%, % to ${tree.symbol}, encl class = ${ctx.owner.enclosingClass}")
outer.path(tree.symbol)
@@ -423,6 +448,9 @@ object Erasure extends TypeTestsCasts{
}
}
+ /** Besides normal typing, this method collects all arguments
+ * to a compacted function into a single argument of array type.
+ */
override def typedApply(tree: untpd.Apply, pt: Type)(implicit ctx: Context): Tree = {
val Apply(fun, args) = tree
if (fun.symbol == defn.dummyApply)
@@ -434,7 +462,13 @@ object Erasure extends TypeTestsCasts{
fun1.tpe.widen match {
case mt: MethodType =>
val outers = outer.args(fun.asInstanceOf[tpd.Tree]) // can't use fun1 here because its type is already erased
- val args1 = (outers ::: args ++ protoArgs(pt)).zipWithConserve(mt.paramTypes)(typedExpr)
+ var args0 = outers ::: args ++ protoArgs(pt)
+ if (args0.length > MaxImplementedFunctionArity && mt.paramTypes.length == 1) {
+ val bunchedArgs = untpd.JavaSeqLiteral(args0, TypeTree(defn.ObjectType))
+ .withType(defn.ArrayOf(defn.ObjectType))
+ args0 = bunchedArgs :: Nil
+ }
+ val args1 = args0.zipWithConserve(mt.paramTypes)(typedExpr)
untpd.cpy.Apply(tree)(fun1, args1) withType mt.resultType
case _ =>
throw new MatchError(i"tree $tree has unexpected type of function ${fun1.tpe.widen}, was ${fun.typeOpt.widen}")
@@ -470,18 +504,36 @@ object Erasure extends TypeTestsCasts{
super.typedValDef(untpd.cpy.ValDef(vdef)(
tpt = untpd.TypedSplice(TypeTree(sym.info).withPos(vdef.tpt.pos))), sym)
+ /** Besides normal typing, this function also compacts anonymous functions
+ * with more than `MaxImplementedFunctionArity` parameters to ise a single
+ * parameter of type `[]Object`.
+ */
override def typedDefDef(ddef: untpd.DefDef, sym: Symbol)(implicit ctx: Context) = {
val restpe =
if (sym.isConstructor) defn.UnitType
else sym.info.resultType
+ var vparamss1 = (outer.paramDefs(sym) ::: ddef.vparamss.flatten) :: Nil
+ var rhs1 = ddef.rhs match {
+ case id @ Ident(nme.WILDCARD) => untpd.TypedSplice(id.withType(restpe))
+ case _ => ddef.rhs
+ }
+ if (sym.isAnonymousFunction && vparamss1.head.length > MaxImplementedFunctionArity) {
+ val bunchedParam = ctx.newSymbol(sym, nme.ALLARGS, Flags.TermParam, JavaArrayType(defn.ObjectType))
+ def selector(n: Int) = ref(bunchedParam)
+ .select(defn.Array_apply)
+ .appliedTo(Literal(Constant(n)))
+ val paramDefs = vparamss1.head.zipWithIndex.map {
+ case (paramDef, idx) =>
+ assignType(untpd.cpy.ValDef(paramDef)(rhs = selector(idx)), paramDef.symbol)
+ }
+ vparamss1 = (tpd.ValDef(bunchedParam) :: Nil) :: Nil
+ rhs1 = untpd.Block(paramDefs, rhs1)
+ }
val ddef1 = untpd.cpy.DefDef(ddef)(
tparams = Nil,
- vparamss = (outer.paramDefs(sym) ::: ddef.vparamss.flatten) :: Nil,
+ vparamss = vparamss1,
tpt = untpd.TypedSplice(TypeTree(restpe).withPos(ddef.tpt.pos)),
- rhs = ddef.rhs match {
- case id @ Ident(nme.WILDCARD) => untpd.TypedSplice(id.withType(restpe))
- case _ => ddef.rhs
- })
+ rhs = rhs1)
super.typedDefDef(ddef1, sym)
}
@@ -525,7 +577,7 @@ object Erasure extends TypeTestsCasts{
val bridge = ctx.newSymbol(ctx.owner, nme.ANON_FUN, Flags.Synthetic | Flags.Method, sam.info)
val bridgeCtx = ctx.withOwner(bridge)
Closure(bridge, bridgeParamss => {
- implicit val ctx: Context = bridgeCtx
+ implicit val ctx = bridgeCtx
val List(bridgeParams) = bridgeParamss
val rhs = Apply(meth, (bridgeParams, implParamTypes).zipped.map(adapt(_, _)))
@@ -641,7 +693,7 @@ object Erasure extends TypeTestsCasts{
val bridgeCtx = ctx.withOwner(bridge)
tpd.DefDef(bridge, { paramss: List[List[tpd.Tree]] =>
- implicit val ctx: Context = bridgeCtx
+ implicit val ctx = bridgeCtx
val rhs = paramss.foldLeft(sel)((fun, vparams) =>
fun.tpe.widen match {
diff --git a/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala b/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala
index 3fec47e9f..c2aacf826 100644
--- a/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala
+++ b/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala
@@ -81,21 +81,26 @@ class ExplicitOuter extends MiniPhaseTransform with InfoTransformer { thisTransf
!needsOuterAlways(cls) &&
impl.existsSubTree(referencesOuter(cls, _)))
ensureOuterAccessors(cls)
- if (hasOuter(cls)) {
+
+ val clsHasOuter = hasOuter(cls)
+ if (clsHasOuter || cls.mixins.exists(needsOuterIfReferenced)) {
val newDefs = new mutable.ListBuffer[Tree]
- if (isTrait)
- newDefs += DefDef(outerAccessor(cls).asTerm, EmptyTree)
- else {
- val outerParamAcc = outerParamAccessor(cls)
- newDefs += ValDef(outerParamAcc, EmptyTree)
- newDefs += DefDef(outerAccessor(cls).asTerm, ref(outerParamAcc))
+
+ if (clsHasOuter) {
+ if (isTrait)
+ newDefs += DefDef(outerAccessor(cls).asTerm, EmptyTree)
+ else {
+ val outerParamAcc = outerParamAccessor(cls)
+ newDefs += ValDef(outerParamAcc, EmptyTree)
+ newDefs += DefDef(outerAccessor(cls).asTerm, ref(outerParamAcc))
+ }
}
for (parentTrait <- cls.mixins) {
if (needsOuterIfReferenced(parentTrait)) {
val parentTp = cls.denot.thisType.baseTypeRef(parentTrait)
val outerAccImpl = newOuterAccessor(cls, parentTrait).enteredAfter(thisTransformer)
- newDefs += DefDef(outerAccImpl, singleton(outerPrefix(parentTp)))
+ newDefs += DefDef(outerAccImpl, singleton(fixThis(outerPrefix(parentTp))))
}
}
@@ -147,7 +152,8 @@ object ExplicitOuter {
private def newOuterSym(owner: ClassSymbol, cls: ClassSymbol, name: TermName, flags: FlagSet)(implicit ctx: Context) = {
val target = cls.owner.enclosingClass.typeRef
val info = if (flags.is(Method)) ExprType(target) else target
- ctx.newSymbol(owner, name, Synthetic | flags, info, coord = cls.coord)
+ ctx.withPhaseNoEarlier(ctx.explicitOuterPhase.next) // outer accessors are entered at explicitOuter + 1, should not be defined before.
+ .newSymbol(owner, name, Synthetic | flags, info, coord = cls.coord)
}
/** A new param accessor for the outer field in class `cls` */
@@ -180,6 +186,7 @@ object ExplicitOuter {
private def needsOuterAlways(cls: ClassSymbol)(implicit ctx: Context): Boolean =
needsOuterIfReferenced(cls) &&
(!hasLocalInstantiation(cls) || // needs outer because we might not know whether outer is referenced or not
+ cls.mixins.exists(needsOuterIfReferenced) || // needs outer for parent traits
cls.classInfo.parents.exists(parent => // needs outer to potentially pass along to parent
needsOuterIfReferenced(parent.classSymbol.asClass)))
@@ -269,12 +276,32 @@ object ExplicitOuter {
if (tpe.prefix eq NoPrefix) cls.owner.enclosingClass.thisType
else tpe.prefix
case _ =>
- outerPrefix(tpe.underlying)
+ // Need to be careful to dealias before erasure, otherwise we lose prefixes.
+ outerPrefix(tpe.underlying(ctx.withPhaseNoLater(ctx.erasurePhase)))
}
case tpe: TypeProxy =>
outerPrefix(tpe.underlying)
}
+ /** It's possible (i1755.scala gives an example) that the type
+ * given by outerPrefix contains a This-reference to a module outside
+ * the context where that module is defined. This needs to be translated
+ * to an access to the module object from the enclosing class or object.
+ *
+ * This solution is a bit of a hack; it would be better to avoid
+ * such references to the This of a module from outside the module
+ * in the first place. I was not yet able to find out how such references
+ * arise and how to avoid them.
+ */
+ private def fixThis(tpe: Type)(implicit ctx: Context): Type = tpe match {
+ case tpe: ThisType if tpe.cls.is(Module) && !ctx.owner.isContainedIn(tpe.cls) =>
+ fixThis(TermRef(tpe.cls.owner.thisType, tpe.cls.sourceModule.asTerm))
+ case tpe: TermRef =>
+ tpe.derivedSelect(fixThis(tpe.prefix))
+ case _ =>
+ tpe
+ }
+
def outer(implicit ctx: Context): OuterOps = new OuterOps(ctx)
/** The operations in this class
@@ -313,7 +340,7 @@ object ExplicitOuter {
val cls = fun.symbol.owner.asClass
def outerArg(receiver: Tree): Tree = receiver match {
case New(_) | Super(_, _) =>
- singleton(outerPrefix(receiver.tpe))
+ singleton(fixThis(outerPrefix(receiver.tpe)))
case This(_) =>
ref(outerParamAccessor(cls)) // will be rewired to outer argument of secondary constructor in phase Constructors
case TypeApply(Select(r, nme.asInstanceOf_), args) =>
@@ -330,7 +357,7 @@ object ExplicitOuter {
/** The path of outer accessors that references `toCls.this` starting from
* the context owner's this node.
*/
- def path(toCls: Symbol, start: Tree = This(ctx.owner.enclosingClass.asClass)): Tree = try {
+ def path(toCls: Symbol, start: Tree = This(ctx.owner.lexicallyEnclosingClass.asClass)): Tree = try {
def loop(tree: Tree): Tree = {
val treeCls = tree.tpe.widen.classSymbol
val outerAccessorCtx = ctx.withPhaseNoLater(ctx.lambdaLiftPhase) // lambdalift mangles local class names, which means we cannot reliably find outer acessors anymore
diff --git a/compiler/src/dotty/tools/dotc/transform/ExtensionMethods.scala b/compiler/src/dotty/tools/dotc/transform/ExtensionMethods.scala
index 5ae4e8a54..925ec08b2 100644
--- a/compiler/src/dotty/tools/dotc/transform/ExtensionMethods.scala
+++ b/compiler/src/dotty/tools/dotc/transform/ExtensionMethods.scala
@@ -135,14 +135,6 @@ class ExtensionMethods extends MiniPhaseTransform with DenotTransformer with Ful
// TODO: this is state and should be per-run
// todo: check that when transformation finished map is empty
- private def checkNonCyclic(pos: Position, seen: Set[Symbol], clazz: ClassSymbol)(implicit ctx: Context): Unit =
- if (seen contains clazz)
- ctx.error("value class may not unbox to itself", pos)
- else {
- val unboxed = underlyingOfValueClass(clazz).typeSymbol
- if (isDerivedValueClass(unboxed)) checkNonCyclic(pos, seen + clazz, unboxed.asClass)
- }
-
override def transformTemplate(tree: tpd.Template)(implicit ctx: Context, info: TransformerInfo): tpd.Tree = {
if (isDerivedValueClass(ctx.owner)) {
/* This is currently redundant since value classes may not
diff --git a/compiler/src/dotty/tools/dotc/transform/InterceptedMethods.scala b/compiler/src/dotty/tools/dotc/transform/InterceptedMethods.scala
index 7c60e8d72..21ca8dbfd 100644
--- a/compiler/src/dotty/tools/dotc/transform/InterceptedMethods.scala
+++ b/compiler/src/dotty/tools/dotc/transform/InterceptedMethods.scala
@@ -96,14 +96,24 @@ class InterceptedMethods extends MiniPhaseTransform {
s"that means the intercepted methods set doesn't match the code")
tree
}
- lazy val Select(qual, _) = tree.fun
+ lazy val qual = tree.fun match {
+ case Select(qual, _) => qual
+ case ident @ Ident(_) =>
+ ident.tpe match {
+ case TermRef(prefix: TermRef, _) =>
+ tpd.ref(prefix)
+ case TermRef(prefix: ThisType, _) =>
+ tpd.This(prefix.cls)
+ }
+
+ }
val Any_## = this.Any_##
val Any_!= = defn.Any_!=
val rewrite: Tree = tree.fun.symbol match {
case Any_## =>
- poundPoundValue(qual)
+ poundPoundValue(qual)
case Any_!= =>
- qual.select(defn.Any_==).appliedToArgs(tree.args).select(defn.Boolean_!)
+ qual.select(defn.Any_==).appliedToArgs(tree.args).select(defn.Boolean_!)
/*
/* else if (isPrimitiveValueClass(qual.tpe.typeSymbol)) {
// todo: this is needed to support value classes
@@ -121,7 +131,7 @@ class InterceptedMethods extends MiniPhaseTransform {
// we get a primitive form of _getClass trying to target a boxed value
// so we need replace that method name with Object_getClass to get correct behavior.
// See SI-5568.
- qual.selectWithSig(defn.Any_getClass).appliedToNone
+ qual.selectWithSig(defn.Any_getClass).appliedToNone
case _ =>
tree
}
diff --git a/compiler/src/dotty/tools/dotc/transform/LazyVals.scala b/compiler/src/dotty/tools/dotc/transform/LazyVals.scala
index e63a7c3a7..a6ac71286 100644
--- a/compiler/src/dotty/tools/dotc/transform/LazyVals.scala
+++ b/compiler/src/dotty/tools/dotc/transform/LazyVals.scala
@@ -141,7 +141,7 @@ class LazyVals extends MiniPhaseTransform with IdentityDenotTransformer {
val initSymbol = ctx.newSymbol(x.symbol.owner, initName, initFlags, MethodType(Nil, tpe), coord = x.pos)
val result = ref(holderSymbol).select(lazyNme.value)
val flag = ref(holderSymbol).select(lazyNme.initialized)
- val initer = valueInitter.changeOwner(x.symbol, initSymbol)
+ val initer = valueInitter.changeOwnerAfter(x.symbol, initSymbol, this)
val initBody =
adaptToType(
ref(holderSymbol).select(defn.Object_synchronized).appliedTo(
diff --git a/compiler/src/dotty/tools/dotc/transform/LiftTry.scala b/compiler/src/dotty/tools/dotc/transform/LiftTry.scala
index 6a273b91e..d01195614 100644
--- a/compiler/src/dotty/tools/dotc/transform/LiftTry.scala
+++ b/compiler/src/dotty/tools/dotc/transform/LiftTry.scala
@@ -57,7 +57,7 @@ class LiftTry extends MiniPhase with IdentityDenotTransformer { thisTransform =>
ctx.debuglog(i"lifting tree at ${tree.pos}, current owner = ${ctx.owner}")
val fn = ctx.newSymbol(
ctx.owner, ctx.freshName("liftedTree").toTermName, Synthetic | Method,
- MethodType(Nil, tree.tpe), coord = tree.pos)
+ MethodType(Nil, tree.tpe.widenIfUnstable), coord = tree.pos)
tree.changeOwnerAfter(ctx.owner, fn, thisTransform)
Block(DefDef(fn, tree) :: Nil, ref(fn).appliedToNone)
}
diff --git a/compiler/src/dotty/tools/dotc/transform/Memoize.scala b/compiler/src/dotty/tools/dotc/transform/Memoize.scala
index 01c240e3a..8b5ceb0aa 100644
--- a/compiler/src/dotty/tools/dotc/transform/Memoize.scala
+++ b/compiler/src/dotty/tools/dotc/transform/Memoize.scala
@@ -47,7 +47,9 @@ import Decorators._
}
tree match {
case ddef: DefDef
- if !ddef.symbol.is(Deferred) && ddef.rhs == EmptyTree =>
+ if !ddef.symbol.is(Deferred) &&
+ !ddef.symbol.isConstructor && // constructors bodies are added later at phase Constructors
+ ddef.rhs == EmptyTree =>
errorLackImplementation(ddef)
case tdef: TypeDef
if tdef.symbol.isClass && !tdef.symbol.is(Deferred) && tdef.rhs == EmptyTree =>
@@ -89,32 +91,19 @@ import Decorators._
}
lazy val field = sym.field.orElse(newField).asTerm
-
+
def adaptToField(tree: Tree) =
if (tree.isEmpty) tree else tree.ensureConforms(field.info.widen)
-
- if (sym.is(Accessor, butNot = NoFieldNeeded))
- if (sym.isGetter) {
- def skipBlocks(t: Tree): Tree = t match {
- case Block(_, t1) => skipBlocks(t1)
- case _ => t
- }
- skipBlocks(tree.rhs) match {
- case lit: Literal if sym.is(Final) && isIdempotentExpr(tree.rhs) =>
- // duplicating scalac behavior: for final vals that have rhs as constant, we do not create a field
- // and instead return the value. This seemingly minor optimization has huge effect on initialization
- // order and the values that can be observed during superconstructor call
- // see remark about idempotency in PostTyper#normalizeTree
- cpy.DefDef(tree)(rhs = lit)
- case _ =>
- var rhs = tree.rhs.changeOwnerAfter(sym, field, thisTransform)
- if (isWildcardArg(rhs)) rhs = EmptyTree
+ val NoFieldNeeded = Lazy | Deferred | JavaDefined | (if (ctx.settings.YnoInline.value) EmptyFlags else Inline)
- val fieldDef = transformFollowing(ValDef(field, adaptToField(rhs)))
- val getterDef = cpy.DefDef(tree)(rhs = transformFollowingDeep(ref(field))(ctx.withOwner(sym), info))
- Thicket(fieldDef, getterDef)
- }
+ if (sym.is(Accessor, butNot = NoFieldNeeded))
+ if (sym.isGetter) {
+ var rhs = tree.rhs.changeOwnerAfter(sym, field, thisTransform)
+ if (isWildcardArg(rhs)) rhs = EmptyTree
+ val fieldDef = transformFollowing(ValDef(field, adaptToField(rhs)))
+ val getterDef = cpy.DefDef(tree)(rhs = transformFollowingDeep(ref(field))(ctx.withOwner(sym), info))
+ Thicket(fieldDef, getterDef)
} else if (sym.isSetter) {
if (!sym.is(ParamAccessor)) { val Literal(Constant(())) = tree.rhs } // this is intended as an assertion
field.setFlag(Mutable) // necessary for vals mixed in from Scala2 traits
@@ -125,5 +114,4 @@ import Decorators._
// neither getters nor setters
else tree
}
- private val NoFieldNeeded = Lazy | Deferred | JavaDefined
}
diff --git a/compiler/src/dotty/tools/dotc/transform/ParamForwarding.scala b/compiler/src/dotty/tools/dotc/transform/ParamForwarding.scala
index 9571c387b..a72e10681 100644
--- a/compiler/src/dotty/tools/dotc/transform/ParamForwarding.scala
+++ b/compiler/src/dotty/tools/dotc/transform/ParamForwarding.scala
@@ -55,7 +55,9 @@ class ParamForwarding(thisTransformer: DenotTransformer) {
stat match {
case stat: ValDef =>
val sym = stat.symbol.asTerm
- if (sym is (ParamAccessor, butNot = Mutable)) {
+ if (sym.is(ParamAccessor, butNot = Mutable) && !sym.info.isInstanceOf[ExprType]) {
+ // ElimByName gets confused with methods returning an ExprType,
+ // so avoid param forwarding if parameter is by name. See i1766.scala
val idx = superArgs.indexWhere(_.symbol == sym)
if (idx >= 0 && superParamNames(idx) == stat.name) { // supercall to like-named parameter
val alias = inheritedAccessor(sym)
diff --git a/compiler/src/dotty/tools/dotc/transform/PatternMatcher.scala b/compiler/src/dotty/tools/dotc/transform/PatternMatcher.scala
index 3e25cf82e..181dfccd9 100644
--- a/compiler/src/dotty/tools/dotc/transform/PatternMatcher.scala
+++ b/compiler/src/dotty/tools/dotc/transform/PatternMatcher.scala
@@ -235,14 +235,21 @@ class PatternMatcher extends MiniPhaseTransform with DenotTransformer {
// next: MatchMonad[U]
// returns MatchMonad[U]
def flatMap(prev: Tree, b: Symbol, next: Tree): Tree = {
-
- val getTp = extractorMemberType(prev.tpe, nme.get)
- val isDefined = extractorMemberType(prev.tpe, nme.isDefined)
-
- if ((isDefined isRef defn.BooleanClass) && getTp.exists) {
- // isDefined and get may be overloaded
- val getDenot = prev.tpe.member(nme.get).suchThat(_.info.isParameterless)
- val isDefinedDenot = prev.tpe.member(nme.isDefined).suchThat(_.info.isParameterless)
+ val resultArity = defn.productArity(b.info)
+ if (isProductMatch(prev.tpe, resultArity)) {
+ val nullCheck: Tree = prev.select(defn.Object_ne).appliedTo(Literal(Constant(null)))
+ ifThenElseZero(
+ nullCheck,
+ Block(
+ List(ValDef(b.asTerm, prev)),
+ next //Substitution(b, ref(prevSym))(next)
+ )
+ )
+ }
+ else {
+ val getDenot = extractorMember(prev.tpe, nme.get)
+ val isEmptyDenot = extractorMember(prev.tpe, nme.isEmpty)
+ assert(getDenot.exists && isEmptyDenot.exists, i"${prev.tpe}")
val tmpSym = freshSym(prev.pos, prev.tpe, "o")
val prevValue = ref(tmpSym).select(getDenot.symbol).ensureApplied
@@ -251,20 +258,10 @@ class PatternMatcher extends MiniPhaseTransform with DenotTransformer {
List(ValDef(tmpSym, prev)),
// must be isEmpty and get as we don't control the target of the call (prev is an extractor call)
ifThenElseZero(
- ref(tmpSym).select(isDefinedDenot.symbol),
+ ref(tmpSym).select(isEmptyDenot.symbol).select(defn.Boolean_!),
Block(List(ValDef(b.asTerm, prevValue)), next)
)
)
- } else {
- assert(defn.isProductSubType(prev.tpe))
- val nullCheck: Tree = prev.select(defn.Object_ne).appliedTo(Literal(Constant(null)))
- ifThenElseZero(
- nullCheck,
- Block(
- List(ValDef(b.asTerm, prev)),
- next //Substitution(b, ref(prevSym))(next)
- )
- )
}
}
@@ -1431,12 +1428,12 @@ class PatternMatcher extends MiniPhaseTransform with DenotTransformer {
case _ => or
}
- def resultInMonad = if (aligner.isBool) defn.UnitType else {
- val getTp = extractorMemberType(resultType, nme.get)
- if ((extractorMemberType(resultType, nme.isDefined) isRef defn.BooleanClass) && getTp.exists)
- getTp
+ def resultInMonad =
+ if (aligner.isBool) defn.UnitType
+ else if (isProductMatch(resultType, aligner.prodArity)) resultType
+ else if (isGetMatch(resultType)) extractorMemberType(resultType, nme.get)
else resultType
- }
+
def resultType: Type
/** Create the TreeMaker that embodies this extractor call
@@ -1632,13 +1629,12 @@ class PatternMatcher extends MiniPhaseTransform with DenotTransformer {
//val spr = subPatRefs(binder)
assert(go && go1)
ref(binder) :: Nil
- } else {
- lazy val getTp = extractorMemberType(binderTypeTested, nme.get)
- if ((aligner.isSingle && aligner.extractor.prodArity == 1) && ((extractorMemberType(binderTypeTested, nme.isDefined) isRef defn.BooleanClass) && getTp.exists))
- List(ref(binder))
- else
- subPatRefs(binder)
}
+ else if ((aligner.isSingle && aligner.extractor.prodArity == 1) &&
+ !isProductMatch(binderTypeTested, aligner.prodArity) && isGetMatch(binderTypeTested))
+ List(ref(binder))
+ else
+ subPatRefs(binder)
}
/*protected def spliceApply(binder: Symbol): Tree = {
@@ -1890,9 +1886,8 @@ class PatternMatcher extends MiniPhaseTransform with DenotTransformer {
else if (result.classSymbol is Flags.CaseClass) result.decls.filter(x => x.is(Flags.CaseAccessor) && x.is(Flags.Method)).map(_.info).toList
else result.select(nme.get) :: Nil
)*/
- if ((extractorMemberType(resultType, nme.isDefined) isRef defn.BooleanClass) && resultOfGet.exists)
- getUnapplySelectors(resultOfGet, args)
- else if (defn.isProductSubType(resultType)) productSelectorTypes(resultType)
+ if (isProductMatch(resultType, args.length)) productSelectorTypes(resultType)
+ else if (isGetMatch(resultType)) getUnapplySelectors(resultOfGet, args)
else if (resultType isRef defn.BooleanClass) Nil
else {
ctx.error(i"invalid return type in Unapply node: $resultType")
diff --git a/compiler/src/dotty/tools/dotc/transform/ShortcutImplicits.scala b/compiler/src/dotty/tools/dotc/transform/ShortcutImplicits.scala
new file mode 100644
index 000000000..b5469610f
--- /dev/null
+++ b/compiler/src/dotty/tools/dotc/transform/ShortcutImplicits.scala
@@ -0,0 +1,165 @@
+package dotty.tools.dotc
+package transform
+
+import TreeTransforms._
+import core.DenotTransformers.IdentityDenotTransformer
+import core.Symbols._
+import core.Contexts._
+import core.Types._
+import core.Flags._
+import core.Decorators._
+import core.StdNames.nme
+import core.Names._
+import core.NameOps._
+import ast.Trees._
+import ast.tpd
+import collection.mutable
+
+/** This phase optimizes code using implicit function types, by applying two rewrite rules.
+ * Let IF be the implicit function type
+ *
+ * implicit Us => R
+ *
+ * (1) A method definition
+ *
+ * def m(xs: Ts): IF = implicit (ys: Us) => E
+ *
+ * is expanded to two methods:
+ *
+ * def m(xs: Ts): IF = implicit (ys: Us) => m$direct(xs)(ys)
+ * def m$direct(xs: Ts)(ys: Us): R = E
+ *
+ * (and equivalently for methods with type parameters or a different number of value parameter lists).
+ * An abstract method definition
+ *
+ * def m(xs: Ts): IF
+ *
+ * is expanded to:
+ *
+ * def m(xs: Ts): IF
+ * def m$direct(xs: Ts)(ys: Us): R
+ *
+ * (2) A reference `qual.apply` where `qual` has implicit function type and
+ * `qual` refers to a method `m` is rewritten to a reference to `m$direct`,
+ * keeping the same type and value arguments as they are found in `qual`.
+ */
+class ShortcutImplicits extends MiniPhase with IdentityDenotTransformer { thisTransform =>
+ import tpd._
+
+ override def phaseName: String = "shortcutImplicits"
+ val treeTransform = new Transform
+
+ /** If this option is true, we don't specialize symbols that are known to be only
+ * targets of monomorphic calls.
+ * The reason for this option is that benchmarks show that on the JVM for monomorphic dispatch
+ * scenarios inlining and escape analysis can often remove all calling overhead, so we might as
+ * well not duplicate the code. We need more experience to decide on the best setting of this option.
+ */
+ final val specializeMonoTargets = true
+
+ class Transform extends TreeTransform {
+ def phase = thisTransform
+
+ override def prepareForUnit(tree: Tree)(implicit ctx: Context) = new Transform
+
+ /** A map to cache mapping local methods to their direct counterparts.
+ * A fresh map is created for each unit.
+ */
+ private val directMeth = new mutable.HashMap[Symbol, Symbol]
+
+ /** Should `sym` get a ..$direct companion?
+ * This is the case if (1) `sym` is a method with an implicit function type as final result type.
+ * However if `specializeMonoTargets` is false, we exclude symbols that are known
+ * to be only targets of monomorphic calls because they are effectively
+ * final and don't override anything.
+ */
+ private def shouldBeSpecialized(sym: Symbol)(implicit ctx: Context) =
+ sym.is(Method, butNot = Accessor) &&
+ defn.isImplicitFunctionType(sym.info.finalResultType) &&
+ (specializeMonoTargets || !sym.isEffectivelyFinal || sym.allOverriddenSymbols.nonEmpty)
+
+ /** @pre The type's final result type is an implicit function type `implicit Ts => R`.
+ * @return The type of the `apply` member of `implicit Ts => R`.
+ */
+ private def directInfo(info: Type)(implicit ctx: Context): Type = info match {
+ case info: PolyType => info.derivedPolyType(resType = directInfo(info.resultType))
+ case info: MethodType => info.derivedMethodType(resType = directInfo(info.resultType))
+ case info: ExprType => directInfo(info.resultType)
+ case info => info.member(nme.apply).info
+ }
+
+ /** A new `m$direct` method to accompany the given method `m` */
+ private def newDirectMethod(sym: Symbol)(implicit ctx: Context): Symbol = {
+ val direct = sym.copy(
+ name = sym.name.directName,
+ flags = sym.flags | Synthetic,
+ info = directInfo(sym.info))
+ if (direct.allOverriddenSymbols.isEmpty) direct.resetFlag(Override)
+ direct
+ }
+
+ /** The direct method `m$direct` that accompanies the given method `m`.
+ * Create one if it does not exist already.
+ */
+ private def directMethod(sym: Symbol)(implicit ctx: Context): Symbol =
+ if (sym.owner.isClass) {
+ val direct = sym.owner.info.member(sym.name.directName)
+ .suchThat(_.info matches directInfo(sym.info)).symbol
+ if (direct.maybeOwner == sym.owner) direct
+ else newDirectMethod(sym).enteredAfter(thisTransform)
+ }
+ else directMeth.getOrElseUpdate(sym, newDirectMethod(sym))
+
+
+ /** Transform `qual.apply` occurrences according to rewrite rule (2) above */
+ override def transformSelect(tree: Select)(implicit ctx: Context, info: TransformerInfo) =
+ if (tree.name == nme.apply &&
+ defn.isImplicitFunctionType(tree.qualifier.tpe.widen) &&
+ shouldBeSpecialized(tree.qualifier.symbol)) {
+ def directQual(tree: Tree): Tree = tree match {
+ case Apply(fn, args) => cpy.Apply(tree)(directQual(fn), args)
+ case TypeApply(fn, args) => cpy.TypeApply(tree)(directQual(fn), args)
+ case Block(stats, expr) => cpy.Block(tree)(stats, directQual(expr))
+ case tree: RefTree =>
+ cpy.Ref(tree)(tree.name.directName)
+ .withType(directMethod(tree.symbol).termRef)
+ }
+ directQual(tree.qualifier)
+ } else tree
+
+ /** Transform methods with implicit function type result according to rewrite rule (1) above */
+ override def transformDefDef(mdef: DefDef)(implicit ctx: Context, info: TransformerInfo): Tree = {
+ val original = mdef.symbol
+ if (shouldBeSpecialized(original)) {
+ val direct = directMethod(original)
+
+ def splitClosure(tree: Tree): (List[Type] => List[List[Tree]] => Tree, Tree) = tree match {
+ case Block(Nil, expr) => splitClosure(expr)
+ case Block((meth @ DefDef(nme.ANON_FUN, Nil, clparams :: Nil, _, _)) :: Nil, cl: Closure) =>
+ val tparamSyms = mdef.tparams.map(_.symbol)
+ val vparamSymss = mdef.vparamss.map(_.map(_.symbol))
+ val clparamSyms = clparams.map(_.symbol)
+ val remappedCore = (ts: List[Type]) => (prefss: List[List[Tree]]) =>
+ meth.rhs
+ .subst(tparamSyms ::: (vparamSymss.flatten ++ clparamSyms),
+ ts.map(_.typeSymbol) ::: prefss.flatten.map(_.symbol))
+ .changeOwnerAfter(original, direct, thisTransform)
+ .changeOwnerAfter(meth.symbol, direct, thisTransform)
+ val forwarder = ref(direct)
+ .appliedToTypeTrees(tparamSyms.map(ref(_)))
+ .appliedToArgss(vparamSymss.map(_.map(ref(_))) :+ clparamSyms.map(ref(_)))
+ val fwdClosure = cpy.Block(tree)(cpy.DefDef(meth)(rhs = forwarder) :: Nil, cl)
+ (remappedCore, fwdClosure)
+ case EmptyTree =>
+ (_ => _ => EmptyTree, EmptyTree)
+ }
+
+ val (remappedCore, fwdClosure) = splitClosure(mdef.rhs)
+ val originalDef = cpy.DefDef(mdef)(rhs = fwdClosure)
+ val directDef = polyDefDef(direct.asTerm, remappedCore)
+ Thicket(originalDef, directDef)
+ }
+ else mdef
+ }
+ }
+}
diff --git a/compiler/src/dotty/tools/dotc/transform/SuperAccessors.scala b/compiler/src/dotty/tools/dotc/transform/SuperAccessors.scala
index fea478c9b..3c11827fc 100644
--- a/compiler/src/dotty/tools/dotc/transform/SuperAccessors.scala
+++ b/compiler/src/dotty/tools/dotc/transform/SuperAccessors.scala
@@ -71,21 +71,24 @@ class SuperAccessors(thisTransformer: DenotTransformer) {
val Select(qual, name) = sel
val sym = sel.symbol
val clazz = qual.symbol.asClass
- var supername = name.superName
- if (clazz is Trait) supername = supername.expandedName(clazz)
-
- val superAcc = clazz.info.decl(supername).suchThat(_.signature == sym.signature).symbol orElse {
- ctx.debuglog(s"add super acc ${sym.showLocated} to $clazz")
- val deferredOrPrivate = if (clazz is Trait) Deferred | ExpandedName else Private
- val acc = ctx.newSymbol(
- clazz, supername, SuperAccessor | Artifact | Method | deferredOrPrivate,
- sel.tpe.widenSingleton.ensureMethodic, coord = sym.coord).enteredAfter(thisTransformer)
- // Diagnostic for SI-7091
- if (!accDefs.contains(clazz))
- ctx.error(s"Internal error: unable to store accessor definition in ${clazz}. clazz.hasPackageFlag=${clazz is Package}. Accessor required for ${sel} (${sel.show})", sel.pos)
- else accDefs(clazz) += DefDef(acc, EmptyTree)
- acc
- }
+ var superName = name.superName
+ if (clazz is Trait) superName = superName.expandedName(clazz)
+ val superInfo = sel.tpe.widenSingleton.ensureMethodic
+
+ val superAcc = clazz.info.decl(superName)
+ .suchThat(_.signature == superInfo.signature).symbol
+ .orElse {
+ ctx.debuglog(s"add super acc ${sym.showLocated} to $clazz")
+ val deferredOrPrivate = if (clazz is Trait) Deferred | ExpandedName else Private
+ val acc = ctx.newSymbol(
+ clazz, superName, SuperAccessor | Artifact | Method | deferredOrPrivate,
+ superInfo, coord = sym.coord).enteredAfter(thisTransformer)
+ // Diagnostic for SI-7091
+ if (!accDefs.contains(clazz))
+ ctx.error(s"Internal error: unable to store accessor definition in ${clazz}. clazz.hasPackageFlag=${clazz is Package}. Accessor required for ${sel} (${sel.show})", sel.pos)
+ else accDefs(clazz) += DefDef(acc, EmptyTree)
+ acc
+ }
This(clazz).select(superAcc).withPos(sel.pos)
}
diff --git a/compiler/src/dotty/tools/dotc/transform/TreeChecker.scala b/compiler/src/dotty/tools/dotc/transform/TreeChecker.scala
index aa4eefe43..eee429a87 100644
--- a/compiler/src/dotty/tools/dotc/transform/TreeChecker.scala
+++ b/compiler/src/dotty/tools/dotc/transform/TreeChecker.scala
@@ -129,17 +129,20 @@ class TreeChecker extends Phase with SymTransformer {
try checker.typedExpr(ctx.compilationUnit.tpdTree)(checkingCtx)
catch {
case NonFatal(ex) => //TODO CHECK. Check that we are bootstrapped
- implicit val ctx: Context = checkingCtx
+ implicit val ctx = checkingCtx
println(i"*** error while checking ${ctx.compilationUnit} after phase ${checkingCtx.phase.prev} ***")
throw ex
}
}
- class Checker(phasesToCheck: Seq[Phase]) extends ReTyper {
+ class Checker(phasesToCheck: Seq[Phase]) extends ReTyper with Checking {
val nowDefinedSyms = new mutable.HashSet[Symbol]
val everDefinedSyms = new mutable.HashMap[Symbol, Tree]
+ // don't check value classes after typer, as the constraint about constructors doesn't hold after transform
+ override def checkDerivedValueClass(clazz: Symbol, stats: List[Tree])(implicit ctx: Context) = ()
+
def withDefinedSym[T](tree: untpd.Tree)(op: => T)(implicit ctx: Context): T = tree match {
case tree: DefTree =>
val sym = tree.symbol
diff --git a/compiler/src/dotty/tools/dotc/transform/TreeTransform.scala b/compiler/src/dotty/tools/dotc/transform/TreeTransform.scala
index 5385ca720..b0bd40578 100644
--- a/compiler/src/dotty/tools/dotc/transform/TreeTransform.scala
+++ b/compiler/src/dotty/tools/dotc/transform/TreeTransform.scala
@@ -3,7 +3,6 @@ package dotc
package transform
import dotty.tools.dotc.ast.tpd
-import dotty.tools.dotc.core.Annotations.ConcreteAnnotation
import dotty.tools.dotc.core.Contexts.Context
import dotty.tools.dotc.core.DenotTransformers.{InfoTransformer, DenotTransformer}
import dotty.tools.dotc.core.Denotations.SingleDenotation
@@ -181,10 +180,15 @@ object TreeTransforms {
abstract override def transform(ref: SingleDenotation)(implicit ctx: Context): SingleDenotation =
super.transform(ref) match {
case ref1: SymDenotation if ref1.symbol.isDefinedInCurrentRun =>
- val annotTrees = ref1.annotations.map(_.tree)
+ val annots = ref1.annotations
+ val annotTrees = annots.map(_.tree)
val annotTrees1 = annotTrees.mapConserve(annotationTransformer.macroTransform)
if (annotTrees eq annotTrees1) ref1
- else ref1.copySymDenotation(annotations = annotTrees1.map(new ConcreteAnnotation(_)))
+ else {
+ val derivedAnnots = (annots, annotTrees1).zipped.map((annot, annotTree1) =>
+ annot.derivedAnnotation(annotTree1))
+ ref1.copySymDenotation(annotations = derivedAnnots)
+ }
case ref1 =>
ref1
}
diff --git a/compiler/src/dotty/tools/dotc/transform/ValueClasses.scala b/compiler/src/dotty/tools/dotc/transform/ValueClasses.scala
index 93005c57a..b16d05644 100644
--- a/compiler/src/dotty/tools/dotc/transform/ValueClasses.scala
+++ b/compiler/src/dotty/tools/dotc/transform/ValueClasses.scala
@@ -53,4 +53,14 @@ object ValueClasses {
def underlyingOfValueClass(d: ClassDenotation)(implicit ctx: Context): Type =
valueClassUnbox(d).info.resultType
+ /** Whether a value class wraps itself */
+ def isCyclic(cls: ClassSymbol)(implicit ctx: Context): Boolean = {
+ def recur(seen: Set[Symbol], clazz: ClassSymbol)(implicit ctx: Context): Boolean =
+ (seen contains clazz) || {
+ val unboxed = underlyingOfValueClass(clazz).typeSymbol
+ (isDerivedValueClass(unboxed)) && recur(seen + clazz, unboxed.asClass)
+ }
+
+ recur(Set[Symbol](), cls)
+ }
}
diff --git a/compiler/src/dotty/tools/dotc/typer/Applications.scala b/compiler/src/dotty/tools/dotc/typer/Applications.scala
index 6c398cd72..42c24ffb7 100644
--- a/compiler/src/dotty/tools/dotc/typer/Applications.scala
+++ b/compiler/src/dotty/tools/dotc/typer/Applications.scala
@@ -32,16 +32,37 @@ import reporting.diagnostic.Message
object Applications {
import tpd._
+ def extractorMember(tp: Type, name: Name)(implicit ctx: Context) = {
+ def isPossibleExtractorType(tp: Type) = tp match {
+ case _: MethodType | _: PolyType => false
+ case _ => true
+ }
+ tp.member(name).suchThat(d => isPossibleExtractorType(d.info))
+ }
+
def extractorMemberType(tp: Type, name: Name, errorPos: Position = NoPosition)(implicit ctx: Context) = {
- val ref = tp.member(name).suchThat(_.info.isParameterless)
+ val ref = extractorMember(tp, name)
if (ref.isOverloaded)
errorType(i"Overloaded reference to $ref is not allowed in extractor", errorPos)
- else if (ref.info.isInstanceOf[PolyType])
- errorType(i"Reference to polymorphic $ref: ${ref.info} is not allowed in extractor", errorPos)
- else
- ref.info.widenExpr.dealias
+ ref.info.widenExpr.dealias
}
+ /** Does `tp` fit the "product match" conditions as an unapply result type
+ * for a pattern with `numArgs` subpatterns>
+ * This is the case of `tp` is a subtype of the Product<numArgs> class.
+ */
+ def isProductMatch(tp: Type, numArgs: Int)(implicit ctx: Context) =
+ 0 <= numArgs && numArgs <= Definitions.MaxTupleArity &&
+ tp.derivesFrom(defn.ProductNType(numArgs).typeSymbol)
+
+ /** Does `tp` fit the "get match" conditions as an unapply result type?
+ * This is the case of `tp` has a `get` member as well as a
+ * parameterless `isDefined` member of result type `Boolean`.
+ */
+ def isGetMatch(tp: Type, errorPos: Position = NoPosition)(implicit ctx: Context) =
+ extractorMemberType(tp, nme.isEmpty, errorPos).isRef(defn.BooleanClass) &&
+ extractorMemberType(tp, nme.get, errorPos).exists
+
def productSelectorTypes(tp: Type, errorPos: Position = NoPosition)(implicit ctx: Context): List[Type] = {
val sels = for (n <- Iterator.from(0)) yield extractorMemberType(tp, nme.selectorName(n), errorPos)
sels.takeWhile(_.exists).toList
@@ -61,24 +82,37 @@ object Applications {
def unapplyArgs(unapplyResult: Type, unapplyFn: Tree, args: List[untpd.Tree], pos: Position = NoPosition)(implicit ctx: Context): List[Type] = {
+ val unapplyName = unapplyFn.symbol.name
def seqSelector = defn.RepeatedParamType.appliedTo(unapplyResult.elemType :: Nil)
def getTp = extractorMemberType(unapplyResult, nme.get, pos)
- // println(s"unapply $unapplyResult ${extractorMemberType(unapplyResult, nme.isDefined)}")
- if (extractorMemberType(unapplyResult, nme.isDefined, pos) isRef defn.BooleanClass) {
- if (getTp.exists)
- if (unapplyFn.symbol.name == nme.unapplySeq) {
- val seqArg = boundsToHi(getTp.elemType)
- if (seqArg.exists) return args map Function.const(seqArg)
- }
- else return getUnapplySelectors(getTp, args, pos)
- else if (defn.isProductSubType(unapplyResult)) return productSelectorTypes(unapplyResult, pos)
+ def fail = {
+ ctx.error(i"$unapplyResult is not a valid result type of an $unapplyName method of an extractor", pos)
+ Nil
+ }
+
+ if (unapplyName == nme.unapplySeq) {
+ if (unapplyResult derivesFrom defn.SeqClass) seqSelector :: Nil
+ else if (isGetMatch(unapplyResult, pos)) {
+ val seqArg = boundsToHi(getTp.elemType)
+ if (seqArg.exists) args.map(Function.const(seqArg))
+ else fail
+ }
+ else fail
}
- if (unapplyResult derivesFrom defn.SeqClass) seqSelector :: Nil
- else if (unapplyResult isRef defn.BooleanClass) Nil
else {
- ctx.error(i"$unapplyResult is not a valid result type of an unapply method of an extractor", pos)
- Nil
+ assert(unapplyName == nme.unapply)
+ if (isProductMatch(unapplyResult, args.length))
+ productSelectorTypes(unapplyResult)
+ else if (isGetMatch(unapplyResult, pos))
+ getUnapplySelectors(getTp, args, pos)
+ else if (unapplyResult isRef defn.BooleanClass)
+ Nil
+ else if (defn.isProductSubType(unapplyResult))
+ productSelectorTypes(unapplyResult)
+ // this will cause a "wrong number of arguments in pattern" error later on,
+ // which is better than the message in `fail`.
+ else fail
}
}
@@ -250,8 +284,37 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
/** Splice new method reference into existing application */
def spliceMeth(meth: Tree, app: Tree): Tree = app match {
- case Apply(fn, args) => Apply(spliceMeth(meth, fn), args)
- case TypeApply(fn, targs) => TypeApply(spliceMeth(meth, fn), targs)
+ case Apply(fn, args) =>
+ spliceMeth(meth, fn).appliedToArgs(args)
+ case TypeApply(fn, targs) =>
+ // Note: It is important that the type arguments `targs` are passed in new trees
+ // instead of being spliced in literally. Otherwise, a type argument to a default
+ // method could be constructed as the definition site of the type variable for
+ // that default constructor. This would interpolate type variables too early,
+ // causing lots of tests (among them tasty_unpickleScala2) to fail.
+ //
+ // The test case is in i1757.scala. Here we have a variable `s` and a method `cpy`
+ // defined like this:
+ //
+ // var s
+ // def cpy[X](b: List[Int] = b): B[X] = new B[X](b)
+ //
+ // The call `s.cpy()` then gets expanded to
+ //
+ // { val $1$: B[Int] = this.s
+ // $1$.cpy[X']($1$.cpy$default$1[X']
+ // }
+ //
+ // A type variable gets interpolated if it does not appear in the type
+ // of the current tree and the current tree contains the variable's "definition".
+ // Previously, the polymorphic function tree to which the variable was first added
+ // was taken as the variable's definition. But that fails here because that
+ // tree was `s.cpy` but got transformed into `$1$.cpy`. We now take the type argument
+ // [X'] of the variable as its definition tree, which is more robust. But then
+ // it's crucial that the type tree is not copied directly as argument to
+ // `cpy$default$1`. If it was, the variable `X'` would already be interpolated
+ // when typing the default argument, which is too early.
+ spliceMeth(meth, fn).appliedToTypes(targs.tpes)
case _ => meth
}
@@ -333,7 +396,7 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
val getter = findDefaultGetter(n + numArgs(normalizedFun))
if (getter.isEmpty) missingArg(n)
else {
- addTyped(treeToArg(spliceMeth(getter withPos appPos, normalizedFun)), formal)
+ addTyped(treeToArg(spliceMeth(getter withPos normalizedFun.pos, normalizedFun)), formal)
matchArgs(args1, formals1, n + 1)
}
}
@@ -498,7 +561,7 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
var typedArgs = typedArgBuf.toList
def app0 = cpy.Apply(app)(normalizedFun, typedArgs) // needs to be a `def` because typedArgs can change later
val app1 =
- if (!success) app0.withType(ErrorType)
+ if (!success) app0.withType(UnspecifiedErrorType)
else {
if (!sameSeq(args, orderedArgs)) {
// need to lift arguments to maintain evaluation order in the
@@ -591,21 +654,23 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
}
fun1.tpe match {
- case ErrorType => untpd.cpy.Apply(tree)(fun1, tree.args).withType(ErrorType)
+ case err: ErrorType => untpd.cpy.Apply(tree)(fun1, tree.args).withType(err)
case TryDynamicCallType => typedDynamicApply(tree, pt)
case _ =>
- tryEither {
- implicit ctx => simpleApply(fun1, proto)
- } {
- (failedVal, failedState) =>
- def fail = { failedState.commit(); failedVal }
- // Try once with original prototype and once (if different) with tupled one.
- // The reason we need to try both is that the decision whether to use tupled
- // or not was already taken but might have to be revised when an implicit
- // is inserted on the qualifier.
- tryWithImplicitOnQualifier(fun1, originalProto).getOrElse(
- if (proto eq originalProto) fail
- else tryWithImplicitOnQualifier(fun1, proto).getOrElse(fail))
+ if (originalProto.isDropped) fun1
+ else
+ tryEither {
+ implicit ctx => simpleApply(fun1, proto)
+ } {
+ (failedVal, failedState) =>
+ def fail = { failedState.commit(); failedVal }
+ // Try once with original prototype and once (if different) with tupled one.
+ // The reason we need to try both is that the decision whether to use tupled
+ // or not was already taken but might have to be revised when an implicit
+ // is inserted on the qualifier.
+ tryWithImplicitOnQualifier(fun1, originalProto).getOrElse(
+ if (proto eq originalProto) fail
+ else tryWithImplicitOnQualifier(fun1, proto).getOrElse(fail))
}
}
}
@@ -855,7 +920,7 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
case tp =>
val unapplyErr = if (tp.isError) unapplyFn else notAnExtractor(unapplyFn)
val typedArgsErr = args mapconserve (typed(_, defn.AnyType))
- cpy.UnApply(tree)(unapplyErr, Nil, typedArgsErr) withType ErrorType
+ cpy.UnApply(tree)(unapplyErr, Nil, typedArgsErr) withType unapplyErr.tpe
}
}
@@ -912,9 +977,21 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
}
/** In a set of overloaded applicable alternatives, is `alt1` at least as good as
- * `alt2`? `alt1` and `alt2` are non-overloaded references.
+ * `alt2`? Also used for implicits disambiguation.
+ *
+ * @param alt1, alt2 Non-overloaded references indicating the two choices
+ * @param level1, level2 If alternatives come from a comparison of two contextual
+ * implicit candidates, the nesting levels of the candidates.
+ * In all other cases the nesting levels are both 0.
+ *
+ * An alternative A1 is "as good as" an alternative A2 if it wins or draws in a tournament
+ * that awards one point for each of the following
+ *
+ * - A1 is nested more deeply than A2
+ * - The nesting levels of A1 and A2 are the same, and A1's owner derives from A2's owner
+ * - A1's type is more specific than A2's type.
*/
- def isAsGood(alt1: TermRef, alt2: TermRef)(implicit ctx: Context): Boolean = track("isAsGood") { ctx.traceIndented(i"isAsGood($alt1, $alt2)", overload) {
+ def isAsGood(alt1: TermRef, alt2: TermRef, nesting1: Int = 0, nesting2: Int = 0)(implicit ctx: Context): Boolean = track("isAsGood") { ctx.traceIndented(i"isAsGood($alt1, $alt2)", overload) {
assert(alt1 ne alt2)
@@ -963,7 +1040,7 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
val nestedCtx = ctx.fresh.setExploreTyperState
{
- implicit val ctx: Context = nestedCtx
+ implicit val ctx = nestedCtx
isAsSpecificValueType(tp1, constrained(tp2).resultType)
}
case _ => // (3b)
@@ -1029,9 +1106,9 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
val tp1 = stripImplicit(alt1.widen)
val tp2 = stripImplicit(alt2.widen)
- def winsOwner1 = isDerived(owner1, owner2)
+ def winsOwner1 = nesting1 > nesting2 || isDerived(owner1, owner2)
def winsType1 = isAsSpecific(alt1, tp1, alt2, tp2)
- def winsOwner2 = isDerived(owner2, owner1)
+ def winsOwner2 = nesting2 > nesting1 || isDerived(owner2, owner1)
def winsType2 = isAsSpecific(alt2, tp2, alt1, tp1)
overload.println(i"isAsGood($alt1, $alt2)? $tp1 $tp2 $winsOwner1 $winsType1 $winsOwner2 $winsType2")
@@ -1231,7 +1308,7 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
val alts1 = alts filter pt.isMatchedBy
resolveOverloaded(alts1, pt1, targs1)
- case defn.FunctionOf(args, resultType) =>
+ case defn.FunctionOf(args, resultType, _) =>
narrowByTypes(alts, args, resultType)
case pt =>
@@ -1282,7 +1359,7 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
// (p_1_1, ..., p_m_1) => r_1
// ...
// (p_1_n, ..., p_m_n) => r_n
- val decomposedFormalsForArg: List[Option[(List[Type], Type)]] =
+ val decomposedFormalsForArg: List[Option[(List[Type], Type, Boolean)]] =
formalsForArg.map(defn.FunctionOf.unapply)
if (decomposedFormalsForArg.forall(_.isDefined)) {
val formalParamTypessForArg: List[List[Type]] =
diff --git a/compiler/src/dotty/tools/dotc/typer/Checking.scala b/compiler/src/dotty/tools/dotc/typer/Checking.scala
index 0c5a8e5db..41d9f9572 100644
--- a/compiler/src/dotty/tools/dotc/typer/Checking.scala
+++ b/compiler/src/dotty/tools/dotc/typer/Checking.scala
@@ -29,6 +29,7 @@ import ErrorReporting.{err, errorType}
import config.Printers.typr
import collection.mutable
import SymDenotations.NoCompleter
+import dotty.tools.dotc.transform.ValueClasses._
object Checking {
import tpd._
@@ -55,8 +56,8 @@ object Checking {
def checkBounds(args: List[tpd.Tree], poly: PolyType)(implicit ctx: Context): Unit =
checkBounds(args, poly.paramBounds, _.substParams(poly, _))
- /** Check applied type trees for well-formedness. This means
- * - all arguments are within their corresponding bounds
+ /** Check applied type trees for well-formedness. This means
+ * - all arguments are within their corresponding bounds
* - if type is a higher-kinded application with wildcard arguments,
* check that it or one of its supertypes can be reduced to a normal application.
* Unreducible applications correspond to general existentials, and we
@@ -88,12 +89,12 @@ object Checking {
checkWildcardHKApply(tp.superType, pos)
}
case _ =>
- }
+ }
def checkValidIfHKApply(implicit ctx: Context): Unit =
checkWildcardHKApply(tycon.tpe.appliedTo(args.map(_.tpe)), tree.pos)
checkValidIfHKApply(ctx.addMode(Mode.AllowLambdaWildcardApply))
}
-
+
/** Check that `tp` refers to a nonAbstract class
* and that the instance conforms to the self type of the created class.
*/
@@ -236,8 +237,7 @@ object Checking {
catch {
case ex: CyclicReference =>
if (reportErrors) {
- ctx.error(i"illegal cyclic reference: ${checker.where} ${checker.lastChecked} of $sym refers back to the type itself", sym.pos)
- ErrorType
+ errorType(i"illegal cyclic reference: ${checker.where} ${checker.lastChecked} of $sym refers back to the type itself", sym.pos)
}
else info
}
@@ -406,6 +406,43 @@ object Checking {
notPrivate.errors.foreach { case (msg, pos) => ctx.errorOrMigrationWarning(msg, pos) }
info
}
+
+ /** Verify classes extending AnyVal meet the requirements */
+ def checkDerivedValueClass(clazz: Symbol, stats: List[Tree])(implicit ctx: Context) = {
+ def checkValueClassMember(stat: Tree) = stat match {
+ case _: ValDef if !stat.symbol.is(ParamAccessor) =>
+ ctx.error(s"value class may not define non-parameter field", stat.pos)
+ case d: DefDef if d.symbol.isConstructor =>
+ ctx.error(s"value class may not define secondary constructor", stat.pos)
+ case _: MemberDef | _: Import | EmptyTree =>
+ // ok
+ case _ =>
+ ctx.error(s"value class may not contain initialization statements", stat.pos)
+ }
+ if (isDerivedValueClass(clazz)) {
+ if (clazz.is(Trait))
+ ctx.error("Only classes (not traits) are allowed to extend AnyVal", clazz.pos)
+ if (clazz.is(Abstract))
+ ctx.error("`abstract' modifier cannot be used with value classes", clazz.pos)
+ if (!clazz.isStatic)
+ ctx.error(s"value class may not be a ${if (clazz.owner.isTerm) "local class" else "member of another class"}", clazz.pos)
+ if (isCyclic(clazz.asClass))
+ ctx.error("value class cannot wrap itself", clazz.pos)
+ else {
+ val clParamAccessors = clazz.asClass.paramAccessors.filter(_.isTerm)
+ clParamAccessors match {
+ case List(param) =>
+ if (param.is(Mutable))
+ ctx.error("value class parameter must not be a var", param.pos)
+
+ case _ =>
+ ctx.error("value class needs to have exactly one val parameter", clazz.pos)
+ }
+ }
+ stats.foreach(checkValueClassMember)
+ }
+
+ }
}
trait Checking {
@@ -418,7 +455,7 @@ trait Checking {
/** Check that Java statics and packages can only be used in selections.
*/
def checkValue(tree: Tree, proto: Type)(implicit ctx: Context): tree.type = {
- if (!proto.isInstanceOf[SelectionProto]) {
+ if (!proto.isInstanceOf[SelectionProto] && !proto.isInstanceOf[ApplyingProto]) {
val sym = tree.tpe.termSymbol
// The check is avoided inside Java compilation units because it always fails
// on the singleton type Module.type.
@@ -553,6 +590,10 @@ trait Checking {
errorTree(tpt, ex"Singleton type ${tpt.tpe} is not allowed $where")
}
else tpt
+
+ /** Verify classes extending AnyVal meet the requirements */
+ def checkDerivedValueClass(clazz: Symbol, stats: List[Tree])(implicit ctx: Context) =
+ Checking.checkDerivedValueClass(clazz, stats)
}
trait NoChecking extends Checking {
@@ -568,4 +609,5 @@ trait NoChecking extends Checking {
override def checkParentCall(call: Tree, caller: ClassSymbol)(implicit ctx: Context) = ()
override def checkSimpleKinded(tpt: Tree)(implicit ctx: Context): Tree = tpt
override def checkNotSingleton(tpt: Tree, where: String)(implicit ctx: Context): Tree = tpt
+ override def checkDerivedValueClass(clazz: Symbol, stats: List[Tree])(implicit ctx: Context) = ()
}
diff --git a/compiler/src/dotty/tools/dotc/typer/Dynamic.scala b/compiler/src/dotty/tools/dotc/typer/Dynamic.scala
index b5ace87d3..4039c8b81 100644
--- a/compiler/src/dotty/tools/dotc/typer/Dynamic.scala
+++ b/compiler/src/dotty/tools/dotc/typer/Dynamic.scala
@@ -11,6 +11,7 @@ import dotty.tools.dotc.core.Names.Name
import dotty.tools.dotc.core.StdNames._
import dotty.tools.dotc.core.Types._
import dotty.tools.dotc.core.Decorators._
+import ErrorReporting._
object Dynamic {
def isDynamicMethod(name: Name): Boolean =
@@ -41,10 +42,9 @@ trait Dynamic { self: Typer with Applications =>
def isNamedArg(arg: untpd.Tree): Boolean = arg match { case NamedArg(_, _) => true; case _ => false }
val args = tree.args
val dynName = if (args.exists(isNamedArg)) nme.applyDynamicNamed else nme.applyDynamic
- if (dynName == nme.applyDynamicNamed && untpd.isWildcardStarArgList(args)) {
- ctx.error("applyDynamicNamed does not support passing a vararg parameter", tree.pos)
- tree.withType(ErrorType)
- } else {
+ if (dynName == nme.applyDynamicNamed && untpd.isWildcardStarArgList(args))
+ errorTree(tree, "applyDynamicNamed does not support passing a vararg parameter")
+ else {
def namedArgTuple(name: String, arg: untpd.Tree) = untpd.Tuple(List(Literal(Constant(name)), arg))
def namedArgs = args.map {
case NamedArg(argName, arg) => namedArgTuple(argName.toString, arg)
@@ -89,8 +89,7 @@ trait Dynamic { self: Typer with Applications =>
case TypeApply(Select(qual, name), targs) if !isDynamicMethod(name) =>
typedDynamicAssign(qual, name, targs)
case _ =>
- ctx.error("reassignment to val", tree.pos)
- tree.withType(ErrorType)
+ errorTree(tree, "reassignment to val")
}
}
diff --git a/compiler/src/dotty/tools/dotc/typer/ErrorReporting.scala b/compiler/src/dotty/tools/dotc/typer/ErrorReporting.scala
index a18c83ff8..1238ad568 100644
--- a/compiler/src/dotty/tools/dotc/typer/ErrorReporting.scala
+++ b/compiler/src/dotty/tools/dotc/typer/ErrorReporting.scala
@@ -23,7 +23,7 @@ object ErrorReporting {
def errorType(msg: => Message, pos: Position)(implicit ctx: Context): ErrorType = {
ctx.error(msg, pos)
- ErrorType
+ new ErrorType(msg)
}
def cyclicErrorMsg(ex: CyclicReference)(implicit ctx: Context) = {
@@ -46,11 +46,17 @@ object ErrorReporting {
errorMsg(msg, cx.outer)
}
} else msg
- errorMsg(ex.show, ctx)
+
+ if (cycleSym.is(Implicit, butNot = Method) && cycleSym.owner.isTerm)
+ em"""cyclic reference involving implicit $cycleSym
+ |This happens when the right hand-side of $cycleSym's definition involves an implicit search.
+ |To avoid the error, give $cycleSym an explicit type."""
+ else
+ errorMsg(ex.show, ctx)
}
- def wrongNumberOfArgs(fntpe: Type, kind: String, expectedArgs: List[TypeParamInfo], actual: List[untpd.Tree], pos: Position)(implicit ctx: Context) =
- errorType(WrongNumberOfArgs(fntpe, kind, expectedArgs, actual)(ctx), pos)
+ def wrongNumberOfTypeArgs(fntpe: Type, expectedArgs: List[TypeParamInfo], actual: List[untpd.Tree], pos: Position)(implicit ctx: Context) =
+ errorType(WrongNumberOfTypeArgs(fntpe, expectedArgs, actual)(ctx), pos)
class Errors(implicit ctx: Context) {
diff --git a/compiler/src/dotty/tools/dotc/typer/FrontEnd.scala b/compiler/src/dotty/tools/dotc/typer/FrontEnd.scala
index c444631ae..6eff63e2b 100644
--- a/compiler/src/dotty/tools/dotc/typer/FrontEnd.scala
+++ b/compiler/src/dotty/tools/dotc/typer/FrontEnd.scala
@@ -19,6 +19,15 @@ class FrontEnd extends Phase {
override def isTyper = true
import ast.tpd
+ /** The contexts for compilation units that are parsed but not yet entered */
+ private var remaining: List[Context] = Nil
+
+ /** Does a source file ending with `<name>.scala` belong to a compilation unit
+ * that is parsed but not yet entered?
+ */
+ def stillToBeEntered(name: String): Boolean =
+ remaining.exists(_.compilationUnit.toString.endsWith(name + ".scala"))
+
def monitor(doing: String)(body: => Unit)(implicit ctx: Context) =
try body
catch {
@@ -44,6 +53,12 @@ class FrontEnd extends Phase {
typr.println("entered: " + unit.source)
}
+ def enterAnnotations(implicit ctx: Context) = monitor("annotating") {
+ val unit = ctx.compilationUnit
+ ctx.typer.annotate(unit.untpdTree :: Nil)
+ typr.println("annotated: " + unit.source)
+ }
+
def typeCheck(implicit ctx: Context) = monitor("typechecking") {
val unit = ctx.compilationUnit
unit.tpdTree = ctx.typer.typedExpr(unit.untpdTree)
@@ -69,8 +84,13 @@ class FrontEnd extends Phase {
}
unitContexts foreach (parse(_))
record("parsedTrees", ast.Trees.ntrees)
- unitContexts foreach (enterSyms(_))
- unitContexts foreach (typeCheck(_))
+ remaining = unitContexts
+ while (remaining.nonEmpty) {
+ enterSyms(remaining.head)
+ remaining = remaining.tail
+ }
+ unitContexts.foreach(enterAnnotations(_))
+ unitContexts.foreach(typeCheck(_))
record("total trees after typer", ast.Trees.ntrees)
unitContexts.map(_.compilationUnit).filterNot(discardAfterTyper)
}
diff --git a/compiler/src/dotty/tools/dotc/typer/Implicits.scala b/compiler/src/dotty/tools/dotc/typer/Implicits.scala
index f3dceea71..303953e73 100644
--- a/compiler/src/dotty/tools/dotc/typer/Implicits.scala
+++ b/compiler/src/dotty/tools/dotc/typer/Implicits.scala
@@ -24,16 +24,20 @@ import Constants._
import Applications._
import ProtoTypes._
import ErrorReporting._
+import reporting.diagnostic.MessageContainer
import Inferencing.fullyDefinedType
import Trees._
import Hashable._
import config.Config
-import config.Printers.{implicits, implicitsDetailed}
+import config.Printers.{implicits, implicitsDetailed, typr}
import collection.mutable
/** Implicit resolution */
object Implicits {
+ /** An eligible implicit candidate, consisting of an implicit reference and a nesting level */
+ case class Candidate(ref: TermRef, level: Int)
+
/** A common base class of contextual implicits and of-type implicits which
* represents a set of implicit references.
*/
@@ -41,11 +45,14 @@ object Implicits {
implicit val ctx: Context =
if (initctx == NoContext) initctx else initctx retractMode Mode.ImplicitsEnabled
+ /** The nesting level of this context. Non-zero only in ContextialImplicits */
+ def level: Int = 0
+
/** The implicit references */
def refs: List[TermRef]
/** Return those references in `refs` that are compatible with type `pt`. */
- protected def filterMatching(pt: Type)(implicit ctx: Context): List[TermRef] = track("filterMatching") {
+ protected def filterMatching(pt: Type)(implicit ctx: Context): List[Candidate] = track("filterMatching") {
def refMatches(ref: TermRef)(implicit ctx: Context) = /*ctx.traceIndented(i"refMatches $ref $pt")*/ {
@@ -96,8 +103,9 @@ object Implicits {
}
}
- if (refs.isEmpty) refs
- else refs filter (refMatches(_)(ctx.fresh.addMode(Mode.TypevarsMissContext).setExploreTyperState)) // create a defensive copy of ctx to avoid constraint pollution
+ if (refs.isEmpty) Nil
+ else refs.filter(refMatches(_)(ctx.fresh.addMode(Mode.TypevarsMissContext).setExploreTyperState)) // create a defensive copy of ctx to avoid constraint pollution
+ .map(Candidate(_, level))
}
}
@@ -113,8 +121,8 @@ object Implicits {
buf.toList
}
- /** The implicit references that are eligible for expected type `tp` */
- lazy val eligible: List[TermRef] =
+ /** The candidates that are eligible for expected type `tp` */
+ lazy val eligible: List[Candidate] =
/*>|>*/ track("eligible in tpe") /*<|<*/ {
/*>|>*/ ctx.traceIndented(i"eligible($tp), companions = ${companionRefs.toList}%, %", implicitsDetailed, show = true) /*<|<*/ {
if (refs.nonEmpty && monitored) record(s"check eligible refs in tpe", refs.length)
@@ -134,10 +142,21 @@ object Implicits {
* @param outerCtx the next outer context that makes visible further implicits
*/
class ContextualImplicits(val refs: List[TermRef], val outerImplicits: ContextualImplicits)(initctx: Context) extends ImplicitRefs(initctx) {
- private val eligibleCache = new mutable.AnyRefMap[Type, List[TermRef]]
+ private val eligibleCache = new mutable.AnyRefMap[Type, List[Candidate]]
+
+ /** The level increases if current context has a different owner or scope than
+ * the context of the next-outer ImplicitRefs. This is however disabled under
+ * Scala2 mode, since we do not want to change the implicit disambiguation then.
+ */
+ override val level: Int =
+ if (outerImplicits == null) 1
+ else if (ctx.scala2Mode ||
+ (ctx.owner eq outerImplicits.ctx.owner) &&
+ (ctx.scope eq outerImplicits.ctx.scope)) outerImplicits.level
+ else outerImplicits.level + 1
/** The implicit references that are eligible for type `tp`. */
- def eligible(tp: Type): List[TermRef] = /*>|>*/ track(s"eligible in ctx") /*<|<*/ {
+ def eligible(tp: Type): List[Candidate] = /*>|>*/ track(s"eligible in ctx") /*<|<*/ {
if (tp.hash == NotCached) computeEligible(tp)
else eligibleCache get tp match {
case Some(eligibles) =>
@@ -161,13 +180,13 @@ object Implicits {
}
}
- private def computeEligible(tp: Type): List[TermRef] = /*>|>*/ ctx.traceIndented(i"computeEligible $tp in $refs%, %", implicitsDetailed) /*<|<*/ {
+ private def computeEligible(tp: Type): List[Candidate] = /*>|>*/ ctx.traceIndented(i"computeEligible $tp in $refs%, %", implicitsDetailed) /*<|<*/ {
if (monitored) record(s"check eligible refs in ctx", refs.length)
val ownEligible = filterMatching(tp)
if (outerImplicits == NoContext.implicits) ownEligible
else ownEligible ::: {
- val shadowed = (ownEligible map (_.name)).toSet
- outerImplicits.eligible(tp) filterNot (ref => shadowed contains ref.name)
+ val shadowed = ownEligible.map(_.ref.name).toSet
+ outerImplicits.eligible(tp).filterNot(cand => shadowed.contains(cand.ref.name))
}
}
@@ -197,8 +216,8 @@ object Implicits {
* @param tree The typed tree that needs to be inserted
* @param ctx The context after the implicit search
*/
- case class SearchSuccess(tree: tpd.Tree, ref: TermRef, tstate: TyperState) extends SearchResult {
- override def toString = s"SearchSuccess($tree, $ref)"
+ case class SearchSuccess(tree: tpd.Tree, ref: TermRef, level: Int, tstate: TyperState) extends SearchResult {
+ override def toString = s"SearchSuccess($tree, $ref, $level)"
}
/** A failed search */
@@ -212,6 +231,8 @@ object Implicits {
/** A "no matching implicit found" failure */
case object NoImplicitMatches extends SearchFailure
+ case object DivergingImplicit extends SearchFailure
+
/** A search failure that can show information about the cause */
abstract class ExplainedSearchFailure extends SearchFailure {
protected def pt: Type
@@ -233,9 +254,35 @@ object Implicits {
"\n " + explanation
}
- class NonMatchingImplicit(ref: TermRef, val pt: Type, val argument: tpd.Tree) extends ExplainedSearchFailure {
- def explanation(implicit ctx: Context): String =
- em"${err.refStr(ref)} does not $qualify"
+ class NonMatchingImplicit(ref: TermRef,
+ val pt: Type,
+ val argument: tpd.Tree,
+ trail: List[MessageContainer]) extends ExplainedSearchFailure {
+ private val separator = "\n**** because ****\n"
+
+ /** Replace repeated parts beginning with `separator` by ... */
+ private def elideRepeated(str: String): String = {
+ val startIdx = str.indexOfSlice(separator)
+ val nextIdx = str.indexOfSlice(separator, startIdx + separator.length)
+ if (nextIdx < 0) str
+ else {
+ val prefix = str.take(startIdx)
+ val first = str.slice(startIdx, nextIdx)
+ var rest = str.drop(nextIdx)
+ if (rest.startsWith(first)) {
+ rest = rest.drop(first.length)
+ val dots = "\n\n ...\n"
+ if (!rest.startsWith(dots)) rest = dots ++ rest
+ }
+ prefix ++ first ++ rest
+ }
+ }
+
+ def explanation(implicit ctx: Context): String = {
+ val headMsg = em"${err.refStr(ref)} does not $qualify"
+ val trailMsg = trail.map(mc => i"$separator ${mc.message}").mkString
+ elideRepeated(headMsg ++ trailMsg)
+ }
}
class ShadowedImplicit(ref: TermRef, shadowing: Type, val pt: Type, val argument: tpd.Tree) extends ExplainedSearchFailure {
@@ -273,9 +320,10 @@ trait ImplicitRunInfo { self: RunInfo =>
* a type variable, we need the current context, the current
* runinfo context does not do.
*/
- def implicitScope(tp: Type, liftingCtx: Context): OfTypeImplicits = {
+ def implicitScope(rootTp: Type, liftingCtx: Context): OfTypeImplicits = {
val seen: mutable.Set[Type] = mutable.Set()
+ val incomplete: mutable.Set[Type] = mutable.Set()
/** Replace every typeref that does not refer to a class by a conjunction of class types
* that has the same implicit scope as the original typeref. The motivation for applying
@@ -309,16 +357,23 @@ trait ImplicitRunInfo { self: RunInfo =>
}
}
- def iscopeRefs(tp: Type): TermRefSet =
- if (seen contains tp) EmptyTermRefSet
- else {
- seen += tp
- iscope(tp).companionRefs
- }
-
// todo: compute implicits directly, without going via companionRefs?
def collectCompanions(tp: Type): TermRefSet = track("computeImplicitScope") {
ctx.traceIndented(i"collectCompanions($tp)", implicits) {
+
+ def iscopeRefs(t: Type): TermRefSet = implicitScopeCache.get(t) match {
+ case Some(is) =>
+ is.companionRefs
+ case None =>
+ if (seen contains t) {
+ incomplete += tp // all references to rootTo will be accounted for in `seen` so we return `EmptySet`.
+ EmptyTermRefSet // on the other hand, the refs of `tp` are now not accurate, so `tp` is marked incomplete.
+ } else {
+ seen += t
+ iscope(t).companionRefs
+ }
+ }
+
val comps = new TermRefSet
tp match {
case tp: NamedType =>
@@ -356,7 +411,8 @@ trait ImplicitRunInfo { self: RunInfo =>
* @param isLifted Type `tp` is the result of a `liftToClasses` application
*/
def iscope(tp: Type, isLifted: Boolean = false): OfTypeImplicits = {
- def computeIScope(cacheResult: Boolean) = {
+ val canCache = Config.cacheImplicitScopes && tp.hash != NotCached
+ def computeIScope() = {
val savedEphemeral = ctx.typerState.ephemeral
ctx.typerState.ephemeral = false
try {
@@ -367,33 +423,23 @@ trait ImplicitRunInfo { self: RunInfo =>
else
collectCompanions(tp)
val result = new OfTypeImplicits(tp, refs)(ctx)
- if (ctx.typerState.ephemeral) record("ephemeral cache miss: implicitScope")
- else if (cacheResult) implicitScopeCache(tp) = result
+ if (ctx.typerState.ephemeral)
+ record("ephemeral cache miss: implicitScope")
+ else if (canCache &&
+ ((tp eq rootTp) || // first type traversed is always cached
+ !incomplete.contains(tp) && // other types are cached if they are not incomplete
+ result.companionRefs.forall( // and all their companion refs are cached
+ implicitScopeCache.contains)))
+ implicitScopeCache(tp) = result
result
}
finally ctx.typerState.ephemeral |= savedEphemeral
}
-
- if (tp.hash == NotCached || !Config.cacheImplicitScopes)
- computeIScope(cacheResult = false)
- else implicitScopeCache get tp match {
- case Some(is) => is
- case None =>
- // Implicit scopes are tricky to cache because of loops. For example
- // in `tests/pos/implicit-scope-loop.scala`, the scope of B contains
- // the scope of A which contains the scope of B. We break the loop
- // by returning EmptyTermRefSet in `collectCompanions` for types
- // that we have already seen, but this means that we cannot cache
- // the computed scope of A, it is incomplete.
- // Keeping track of exactly where these loops happen would require a
- // lot of book-keeping, instead we choose to be conservative and only
- // cache scopes before any type has been seen. This is unfortunate
- // because loops are very common for types in scala.collection.
- computeIScope(cacheResult = seen.isEmpty)
- }
+ if (canCache) implicitScopeCache.getOrElse(tp, computeIScope())
+ else computeIScope()
}
- iscope(tp)
+ iscope(rootTp)
}
/** A map that counts the number of times an implicit ref was picked */
@@ -450,7 +496,7 @@ trait Implicits { self: Typer =>
*/
def inferImplicitArg(formal: Type, error: (String => String) => Unit, pos: Position)(implicit ctx: Context): Tree =
inferImplicit(formal, EmptyTree, pos) match {
- case SearchSuccess(arg, _, _) =>
+ case SearchSuccess(arg, _, _, _) =>
arg
case ambi: AmbiguousImplicits =>
error(where => s"ambiguous implicits: ${ambi.explanation} of $where")
@@ -496,6 +542,15 @@ trait Implicits { self: Typer =>
}
private def assumedCanEqual(ltp: Type, rtp: Type)(implicit ctx: Context) = {
+ def eqNullable: Boolean = {
+ val other =
+ if (ltp.isRef(defn.NullClass)) rtp
+ else if (rtp.isRef(defn.NullClass)) ltp
+ else NoType
+
+ (other ne NoType) && !other.derivesFrom(defn.AnyValClass)
+ }
+
val lift = new TypeMap {
def apply(t: Type) = t match {
case t: TypeRef =>
@@ -507,7 +562,7 @@ trait Implicits { self: Typer =>
if (variance > 0) mapOver(t) else t
}
}
- ltp.isError || rtp.isError || ltp <:< lift(rtp) || rtp <:< lift(ltp)
+ ltp.isError || rtp.isError || ltp <:< lift(rtp) || rtp <:< lift(ltp) || eqNullable
}
/** Check that equality tests between types `ltp` and `rtp` make sense */
@@ -587,18 +642,19 @@ trait Implicits { self: Typer =>
val wildProto = implicitProto(pt, wildApprox(_))
/** Search failures; overridden in ExplainedImplicitSearch */
- protected def nonMatchingImplicit(ref: TermRef): SearchFailure = NoImplicitMatches
+ protected def nonMatchingImplicit(ref: TermRef, trail: List[MessageContainer]): SearchFailure = NoImplicitMatches
protected def divergingImplicit(ref: TermRef): SearchFailure = NoImplicitMatches
protected def shadowedImplicit(ref: TermRef, shadowing: Type): SearchFailure = NoImplicitMatches
protected def failedSearch: SearchFailure = NoImplicitMatches
/** Search a list of eligible implicit references */
- def searchImplicits(eligible: List[TermRef], contextual: Boolean): SearchResult = {
+ def searchImplicits(eligible: List[Candidate], contextual: Boolean): SearchResult = {
val constr = ctx.typerState.constraint
/** Try to typecheck an implicit reference */
- def typedImplicit(ref: TermRef)(implicit ctx: Context): SearchResult = track("typedImplicit") { ctx.traceIndented(i"typed implicit $ref, pt = $pt, implicitsEnabled == ${ctx.mode is ImplicitsEnabled}", implicits, show = true) {
+ def typedImplicit(cand: Candidate)(implicit ctx: Context): SearchResult = track("typedImplicit") { ctx.traceIndented(i"typed implicit ${cand.ref}, pt = $pt, implicitsEnabled == ${ctx.mode is ImplicitsEnabled}", implicits, show = true) {
assert(constr eq ctx.typerState.constraint)
+ val ref = cand.ref
var generated: Tree = tpd.ref(ref).withPos(pos)
if (!argument.isEmpty)
generated = typedUnadapted(
@@ -622,13 +678,14 @@ trait Implicits { self: Typer =>
case result: AmbiguousImplicits => true
case _ => false
}
+
def validEqAnyArgs(tp1: Type, tp2: Type) = {
List(tp1, tp2).foreach(fullyDefinedType(_, "eqAny argument", pos))
assumedCanEqual(tp1, tp2) || !hasEq(tp1) && !hasEq(tp2) ||
{ implicits.println(i"invalid eqAny[$tp1, $tp2]"); false }
}
if (ctx.reporter.hasErrors)
- nonMatchingImplicit(ref)
+ nonMatchingImplicit(ref, ctx.reporter.removeBufferedMessages)
else if (contextual && !ctx.mode.is(Mode.ImplicitShadowing) &&
!shadowing.tpe.isError && !refMatches(shadowing)) {
implicits.println(i"SHADOWING $ref in ${ref.termSymbol.owner} is shadowed by $shadowing in ${shadowing.symbol.owner}")
@@ -637,9 +694,9 @@ trait Implicits { self: Typer =>
else generated1 match {
case TypeApply(fn, targs @ (arg1 :: arg2 :: Nil))
if fn.symbol == defn.Predef_eqAny && !validEqAnyArgs(arg1.tpe, arg2.tpe) =>
- nonMatchingImplicit(ref)
+ nonMatchingImplicit(ref, Nil)
case _ =>
- SearchSuccess(generated1, ref, ctx.typerState)
+ SearchSuccess(generated1, ref, cand.level, ctx.typerState)
}
}}
@@ -648,19 +705,20 @@ trait Implicits { self: Typer =>
* @param pending The list of implicit references that remain to be investigated
* @param acc An accumulator of successful matches found so far.
*/
- def rankImplicits(pending: List[TermRef], acc: List[SearchSuccess]): List[SearchSuccess] = pending match {
- case ref :: pending1 =>
+ def rankImplicits(pending: List[Candidate], acc: List[SearchSuccess]): List[SearchSuccess] = pending match {
+ case cand :: pending1 =>
val history = ctx.searchHistory nest wildProto
val result =
- if (history eq ctx.searchHistory) divergingImplicit(ref)
- else typedImplicit(ref)(nestedContext.setNewTyperState.setSearchHistory(history))
+ if (history eq ctx.searchHistory) divergingImplicit(cand.ref)
+ else typedImplicit(cand)(nestedContext.setNewTyperState.setSearchHistory(history))
result match {
case fail: SearchFailure =>
rankImplicits(pending1, acc)
case best: SearchSuccess =>
if (ctx.mode.is(Mode.ImplicitExploration)) best :: Nil
else {
- val newPending = pending1 filter (isAsGood(_, best.ref)(nestedContext.setExploreTyperState))
+ val newPending = pending1.filter(cand1 =>
+ isAsGood(cand1.ref, best.ref, cand1.level, best.level)(nestedContext.setExploreTyperState))
rankImplicits(newPending, best :: acc)
}
}
@@ -689,8 +747,9 @@ trait Implicits { self: Typer =>
/** Convert a (possibly empty) list of search successes into a single search result */
def condense(hits: List[SearchSuccess]): SearchResult = hits match {
case best :: alts =>
- alts find (alt => isAsGood(alt.ref, best.ref)(ctx.fresh.setExploreTyperState)) match {
+ alts find (alt => isAsGood(alt.ref, best.ref, alt.level, best.level)(ctx.fresh.setExploreTyperState)) match {
case Some(alt) =>
+ typr.println(i"ambiguous implicits for $pt: ${best.ref} @ ${best.level}, ${alt.ref} @ ${alt.level}")
/* !!! DEBUG
println(i"ambiguous refs: ${hits map (_.ref) map (_.show) mkString ", "}")
isAsGood(best.ref, alt.ref, explain = true)(ctx.fresh.withExploreTyperState)
@@ -707,16 +766,18 @@ trait Implicits { self: Typer =>
failedSearch
}
+ def ranking(cand: Candidate) = -ctx.runInfo.useCount(cand.ref)
+
/** Sort list of implicit references according to their popularity
* (# of times each was picked in current run).
*/
- def sort(eligible: List[TermRef]) = eligible match {
+ def sort(eligible: List[Candidate]) = eligible match {
case Nil => eligible
case e1 :: Nil => eligible
case e1 :: e2 :: Nil =>
- if (ctx.runInfo.useCount(e1) < ctx.runInfo.useCount(e2)) e2 :: e1 :: Nil
+ if (ranking(e2) < ranking(e1)) e2 :: e1 :: Nil
else eligible
- case _ => eligible.sortBy(-ctx.runInfo.useCount(_))
+ case _ => eligible.sortBy(ranking)
}
condense(rankImplicits(sort(eligible), Nil))
@@ -743,8 +804,8 @@ trait Implicits { self: Typer =>
fail
}
def failures = myFailures.toList
- override def nonMatchingImplicit(ref: TermRef) =
- record(new NonMatchingImplicit(ref, pt, argument))
+ override def nonMatchingImplicit(ref: TermRef, trail: List[MessageContainer]) =
+ record(new NonMatchingImplicit(ref, pt, argument, trail))
override def divergingImplicit(ref: TermRef) =
record(new DivergingImplicit(ref, pt, argument))
override def shadowedImplicit(ref: TermRef, shadowing: Type): SearchFailure =
diff --git a/compiler/src/dotty/tools/dotc/typer/ImportInfo.scala b/compiler/src/dotty/tools/dotc/typer/ImportInfo.scala
index 3aa289181..e44343e70 100644
--- a/compiler/src/dotty/tools/dotc/typer/ImportInfo.scala
+++ b/compiler/src/dotty/tools/dotc/typer/ImportInfo.scala
@@ -95,14 +95,22 @@ class ImportInfo(symf: => Symbol, val selectors: List[untpd.Tree], val isRootImp
/** The root import symbol hidden by this symbol, or NoSymbol if no such symbol is hidden.
* Note: this computation needs to work even for un-initialized import infos, and
* is not allowed to force initialization.
+ *
+ * TODO: Once we have fully bootstrapped, I would prefer if we expressed
+ * unimport with an `override` modifier, and generalized it to all imports.
+ * I believe this would be more transparent than the current set of conditions. E.g.
+ *
+ * override import Predef.{any2stringAdd => _, StringAdd => _, _} // disables String +
+ * override import java.lang.{} // disables all imports
*/
- lazy val hiddenRoot: Symbol = {
- val sym = site.termSymbol
- def hasMaskingSelector = selectors exists {
+ lazy val unimported: Symbol = {
+ lazy val sym = site.termSymbol
+ val hasMaskingSelector = selectors exists {
case Thicket(_ :: Ident(nme.WILDCARD) :: Nil) => true
case _ => false
}
- if ((defn.RootImportTypes exists (_.symbol == sym)) && hasMaskingSelector) sym else NoSymbol
+ if (hasMaskingSelector && defn.RootImportTypes.exists(_.symbol == sym)) sym
+ else NoSymbol
}
override def toString = {
diff --git a/compiler/src/dotty/tools/dotc/typer/Inferencing.scala b/compiler/src/dotty/tools/dotc/typer/Inferencing.scala
index aede4974a..86649d78e 100644
--- a/compiler/src/dotty/tools/dotc/typer/Inferencing.scala
+++ b/compiler/src/dotty/tools/dotc/typer/Inferencing.scala
@@ -119,6 +119,18 @@ object Inferencing {
}
}
+ /** If `tree` has a PolyType, infer its type parameters by comparing with expected type `pt` */
+ def inferTypeParams(tree: Tree, pt: Type)(implicit ctx: Context): Tree = tree.tpe match {
+ case poly: PolyType =>
+ val (poly1, tvars) = constrained(poly, tree)
+ val tree1 = tree.withType(poly1).appliedToTypeTrees(tvars)
+ tree1.tpe <:< pt
+ fullyDefinedType(tree1.tpe, "template parent", tree.pos)
+ tree1
+ case _ =>
+ tree
+ }
+
/** The list of uninstantiated type variables bound by some prefix of type `T` which
* occur in at least one formal parameter type of a prefix application.
* Considered prefixes are:
@@ -216,10 +228,10 @@ object Inferencing {
def interpolateUndetVars(tree: Tree, ownedBy: Symbol)(implicit ctx: Context): Unit = {
val constraint = ctx.typerState.constraint
val qualifies = (tvar: TypeVar) =>
- (tree contains tvar.owningTree) || ownedBy.exists && tvar.owner == ownedBy
+ (tree contains tvar.bindingTree) || ownedBy.exists && tvar.owner == ownedBy
def interpolate() = Stats.track("interpolateUndetVars") {
val tp = tree.tpe.widen
- constr.println(s"interpolate undet vars in ${tp.show}, pos = ${tree.pos}, mode = ${ctx.mode}, undets = ${constraint.uninstVars map (tvar => s"${tvar.show}@${tvar.owningTree.pos}")}")
+ constr.println(s"interpolate undet vars in ${tp.show}, pos = ${tree.pos}, mode = ${ctx.mode}, undets = ${constraint.uninstVars map (tvar => s"${tvar.show}@${tvar.bindingTree.pos}")}")
constr.println(s"qualifying undet vars: ${constraint.uninstVars filter qualifies map (tvar => s"$tvar / ${tvar.show}")}, constraint: ${constraint.show}")
val vs = variances(tp, qualifies)
diff --git a/compiler/src/dotty/tools/dotc/typer/Inliner.scala b/compiler/src/dotty/tools/dotc/typer/Inliner.scala
index 3931fcaf4..09487570d 100644
--- a/compiler/src/dotty/tools/dotc/typer/Inliner.scala
+++ b/compiler/src/dotty/tools/dotc/typer/Inliner.scala
@@ -189,7 +189,7 @@ object Inliner {
if (!ctx.isAfterTyper) {
val inlineCtx = ctx
sym.updateAnnotation(LazyBodyAnnotation { _ =>
- implicit val ctx: Context = inlineCtx
+ implicit val ctx = inlineCtx
ctx.withNoError(treeExpr(ctx))(makeInlineable)
})
}
diff --git a/compiler/src/dotty/tools/dotc/typer/Namer.scala b/compiler/src/dotty/tools/dotc/typer/Namer.scala
index 148cf1da7..1b6e437b5 100644
--- a/compiler/src/dotty/tools/dotc/typer/Namer.scala
+++ b/compiler/src/dotty/tools/dotc/typer/Namer.scala
@@ -528,18 +528,96 @@ class Namer { typer: Typer =>
}
}
- stats foreach expand
+ stats.foreach(expand)
mergeCompanionDefs()
val ctxWithStats = (ctx /: stats) ((ctx, stat) => indexExpanded(stat)(ctx))
createCompanionLinks(ctxWithStats)
ctxWithStats
}
+ /** Add all annotations of definitions in `stats` to the defined symbols */
+ def annotate(stats: List[Tree])(implicit ctx: Context): Unit = {
+ def recur(stat: Tree): Unit = stat match {
+ case pcl: PackageDef =>
+ annotate(pcl.stats)
+ case stat: untpd.MemberDef =>
+ stat.getAttachment(SymOfTree) match {
+ case Some(sym) =>
+ sym.infoOrCompleter match {
+ case info: Completer if !defn.isPredefClass(sym.owner) =>
+ // Annotate Predef methods only when they are completed;
+ // This is necessary to break a cyclic dependence between `Predef`
+ // and `deprecated` in test `compileStdLib`.
+ addAnnotations(sym, stat)(info.creationContext)
+ case _ =>
+ // Annotations were already added as part of the symbol's completion
+ }
+ case none =>
+ assert(stat.typeOpt.exists, i"no symbol for $stat")
+ }
+ case stat: untpd.Thicket =>
+ stat.trees.foreach(recur)
+ case _ =>
+ }
+
+ for (stat <- stats) recur(expanded(stat))
+ }
+
+ /** Add annotations of `stat` to `sym`.
+ * This method can be called twice on a symbol (e.g. once
+ * during the `annotate` phase and then again during completion).
+ * Therefore, care needs to be taken not to add annotations again
+ * that are already added to the symbol.
+ */
+ def addAnnotations(sym: Symbol, stat: MemberDef)(implicit ctx: Context) = {
+ // (1) The context in which an annotation of a top-level class or module is evaluated
+ // is the closest enclosing context which has the enclosing package as owner.
+ // (2) The context in which an annotation for any other symbol is evaluated is the
+ // closest enclosing context which has the owner of the class enclosing the symbol as owner.
+ // E.g in
+ //
+ // package p
+ // import a.b
+ // class C {
+ // import d.e
+ // @ann m() ...
+ // }
+ //
+ // `@ann` is evaluated in the context just outside `C`, where the `a.b`
+ // import is visible but the `d.e` import is forgotten. This measure is necessary
+ // in order to avoid cycles.
+ lazy val annotCtx = {
+ var target = sym.owner.lexicallyEnclosingClass
+ if (!target.is(PackageClass)) target = target.owner
+ var c = ctx
+ while (c.owner != target) c = c.outer
+ c
+ }
+ for (annotTree <- untpd.modsDeco(stat).mods.annotations) {
+ val cls = typedAheadAnnotation(annotTree)(annotCtx)
+ if (sym.unforcedAnnotation(cls).isEmpty) {
+ val ann = Annotation.deferred(cls, implicit ctx => typedAnnotation(annotTree))
+ sym.addAnnotation(ann)
+ if (cls == defn.InlineAnnot && sym.is(Method, butNot = Accessor))
+ sym.setFlag(Inline)
+ }
+ }
+ }
+
+ def indexAndAnnotate(stats: List[Tree])(implicit ctx: Context): Context = {
+ val localCtx = index(stats)
+ annotate(stats)
+ localCtx
+ }
+
/** The completer of a symbol defined by a member def or import (except ClassSymbols) */
class Completer(val original: Tree)(implicit ctx: Context) extends LazyType {
protected def localContext(owner: Symbol) = ctx.fresh.setOwner(owner).setTree(original)
+ /** The context with which this completer was created */
+ def creationContext = ctx
+
protected def typeSig(sym: Symbol): Type = original match {
case original: ValDef =>
if (sym is Module) moduleValSig(sym)
@@ -572,19 +650,6 @@ class Namer { typer: Typer =>
completeInCreationContext(denot)
}
- protected def addAnnotations(denot: SymDenotation): Unit = original match {
- case original: untpd.MemberDef =>
- var hasInlineAnnot = false
- for (annotTree <- untpd.modsDeco(original).mods.annotations) {
- val cls = typedAheadAnnotation(annotTree)
- val ann = Annotation.deferred(cls, implicit ctx => typedAnnotation(annotTree))
- denot.addAnnotation(ann)
- if (cls == defn.InlineAnnot && denot.is(Method, butNot = Accessor))
- denot.setFlag(Inline)
- }
- case _ =>
- }
-
private def addInlineInfo(denot: SymDenotation) = original match {
case original: untpd.DefDef if denot.isInlineMethod =>
Inliner.registerInlineInfo(
@@ -598,7 +663,10 @@ class Namer { typer: Typer =>
* to pick up the context at the point where the completer was created.
*/
def completeInCreationContext(denot: SymDenotation): Unit = {
- addAnnotations(denot)
+ original match {
+ case original: MemberDef => addAnnotations(denot.symbol, original)
+ case _ =>
+ }
addInlineInfo(denot)
denot.info = typeSig(denot.symbol)
Checking.checkWellFormed(denot.symbol)
@@ -615,7 +683,7 @@ class Namer { typer: Typer =>
//println(i"completing type params of $sym in ${sym.owner}")
nestedCtx = localContext(sym).setNewScope
myTypeParams = {
- implicit val ctx: Context = nestedCtx
+ implicit val ctx = nestedCtx
val tparams = original.rhs match {
case PolyTypeTree(tparams, _) => tparams
case _ => Nil
@@ -742,7 +810,7 @@ class Namer { typer: Typer =>
ok
}
- addAnnotations(denot)
+ addAnnotations(denot.symbol, original)
val selfInfo =
if (self.isEmpty) NoType
@@ -765,9 +833,10 @@ class Namer { typer: Typer =>
// accessors, that's why the constructor needs to be completed before
// the parent types are elaborated.
index(constr)
+ annotate(constr :: params)
symbolOfTree(constr).ensureCompleted()
- index(rest)(inClassContext(selfInfo))
+ indexAndAnnotate(rest)(inClassContext(selfInfo))
val tparamAccessors = decls.filter(_ is TypeParamAccessor).toList
val parentTypes = ensureFirstIsClass(parents.map(checkedParentType(_, tparamAccessors)))
@@ -783,23 +852,23 @@ class Namer { typer: Typer =>
}
}
- /** Typecheck tree during completion, and remember result in typedtree map */
- private def typedAheadImpl(tree: Tree, pt: Type)(implicit ctx: Context): tpd.Tree = {
+ /** Typecheck `tree` during completion using `typed`, and remember result in TypedAhead map */
+ def typedAheadImpl(tree: Tree, typed: untpd.Tree => tpd.Tree)(implicit ctx: Context): tpd.Tree = {
val xtree = expanded(tree)
xtree.getAttachment(TypedAhead) match {
case Some(ttree) => ttree
case none =>
- val ttree = typer.typed(tree, pt)
- xtree.pushAttachment(TypedAhead, ttree)
+ val ttree = typed(tree)
+ xtree.putAttachment(TypedAhead, ttree)
ttree
}
}
def typedAheadType(tree: Tree, pt: Type = WildcardType)(implicit ctx: Context): tpd.Tree =
- typedAheadImpl(tree, pt)(ctx retractMode Mode.PatternOrType addMode Mode.Type)
+ typedAheadImpl(tree, typer.typed(_, pt)(ctx retractMode Mode.PatternOrType addMode Mode.Type))
def typedAheadExpr(tree: Tree, pt: Type = WildcardType)(implicit ctx: Context): tpd.Tree =
- typedAheadImpl(tree, pt)(ctx retractMode Mode.PatternOrType)
+ typedAheadImpl(tree, typer.typed(_, pt)(ctx retractMode Mode.PatternOrType))
def typedAheadAnnotation(tree: Tree)(implicit ctx: Context): Symbol = tree match {
case Apply(fn, _) => typedAheadAnnotation(fn)
@@ -810,7 +879,7 @@ class Namer { typer: Typer =>
/** Enter and typecheck parameter list */
def completeParams(params: List[MemberDef])(implicit ctx: Context) = {
- index(params)
+ indexAndAnnotate(params)
for (param <- params) typedAheadExpr(param)
}
@@ -929,11 +998,16 @@ class Namer { typer: Typer =>
lhsType // keep constant types that fill in for a non-constant (to be revised when inline has landed).
else inherited
else {
- if (sym is Implicit) {
- val resStr = if (mdef.isInstanceOf[DefDef]) "result " else ""
- ctx.error(s"${resStr}type of implicit definition needs to be given explicitly", mdef.pos)
+ def missingType(modifier: String) = {
+ ctx.error(s"${modifier}type of implicit definition needs to be given explicitly", mdef.pos)
sym.resetFlag(Implicit)
}
+ if (sym is Implicit)
+ mdef match {
+ case _: DefDef => missingType("result")
+ case _: ValDef if sym.owner.isType => missingType("")
+ case _ =>
+ }
lhsType orElse WildcardType
}
}
@@ -990,7 +1064,7 @@ class Namer { typer: Typer =>
// 3. Info of CP is computed (to be copied to DP).
// 4. CP is completed.
// 5. Info of CP is copied to DP and DP is completed.
- index(tparams)
+ indexAndAnnotate(tparams)
if (isConstructor) sym.owner.typeParams.foreach(_.ensureCompleted())
for (tparam <- tparams) typedAheadExpr(tparam)
diff --git a/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala b/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala
index 9a20a452e..eb46a131f 100644
--- a/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala
+++ b/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala
@@ -40,7 +40,9 @@ object ProtoTypes {
/** Test compatibility after normalization in a fresh typerstate. */
def normalizedCompatible(tp: Type, pt: Type)(implicit ctx: Context) = {
val nestedCtx = ctx.fresh.setExploreTyperState
- isCompatible(normalize(tp, pt)(nestedCtx), pt)(nestedCtx)
+ val normTp = normalize(tp, pt)(nestedCtx)
+ isCompatible(normTp, pt)(nestedCtx) ||
+ pt.isRef(defn.UnitClass) && normTp.isParameterless
}
private def disregardProto(pt: Type)(implicit ctx: Context): Boolean = pt.dealias match {
@@ -250,6 +252,22 @@ object ProtoTypes {
/** Somebody called the `tupled` method of this prototype */
def isTupled: Boolean = myTupled.isInstanceOf[FunProto]
+ /** If true, the application of this prototype was canceled. */
+ private var toDrop: Boolean = false
+
+ /** Cancel the application of this prototype. This can happen for a nullary
+ * application `f()` if `f` refers to a symbol that exists both in parameterless
+ * form `def f` and nullary method form `def f()`. A common example for such
+ * a method is `toString`. If in that case the type in the denotation is
+ * parameterless, we compensate by dropping the application.
+ */
+ def markAsDropped() = {
+ assert(args.isEmpty)
+ toDrop = true
+ }
+
+ def isDropped: Boolean = toDrop
+
override def toString = s"FunProto(${args mkString ","} => $resultType)"
def map(tm: TypeMap)(implicit ctx: Context): FunProto =
@@ -353,20 +371,23 @@ object ProtoTypes {
* Also, if `owningTree` is non-empty, add a type variable for each parameter.
* @return The added polytype, and the list of created type variables.
*/
- def constrained(pt: PolyType, owningTree: untpd.Tree)(implicit ctx: Context): (PolyType, List[TypeVar]) = {
+ def constrained(pt: PolyType, owningTree: untpd.Tree)(implicit ctx: Context): (PolyType, List[TypeTree]) = {
val state = ctx.typerState
assert(!(ctx.typerState.isCommittable && owningTree.isEmpty),
s"inconsistent: no typevars were added to committable constraint ${state.constraint}")
- def newTypeVars(pt: PolyType): List[TypeVar] =
+ def newTypeVars(pt: PolyType): List[TypeTree] =
for (n <- (0 until pt.paramNames.length).toList)
- yield new TypeVar(PolyParam(pt, n), state, owningTree, ctx.owner)
+ yield {
+ val tt = new TypeTree().withPos(owningTree.pos)
+ tt.withType(new TypeVar(PolyParam(pt, n), state, tt, ctx.owner))
+ }
val added =
if (state.constraint contains pt) pt.newLikeThis(pt.paramNames, pt.paramBounds, pt.resultType)
else pt
val tvars = if (owningTree.isEmpty) Nil else newTypeVars(added)
- ctx.typeComparer.addToConstraint(added, tvars)
+ ctx.typeComparer.addToConstraint(added, tvars.tpes.asInstanceOf[List[TypeVar]])
(added, tvars)
}
diff --git a/compiler/src/dotty/tools/dotc/typer/ReTyper.scala b/compiler/src/dotty/tools/dotc/typer/ReTyper.scala
index 2413c0c22..3252ead47 100644
--- a/compiler/src/dotty/tools/dotc/typer/ReTyper.scala
+++ b/compiler/src/dotty/tools/dotc/typer/ReTyper.scala
@@ -72,9 +72,10 @@ class ReTyper extends Typer {
override def localTyper(sym: Symbol) = this
override def index(trees: List[untpd.Tree])(implicit ctx: Context) = ctx
+ override def annotate(trees: List[untpd.Tree])(implicit ctx: Context) = ()
- override def tryInsertApplyOrImplicit(tree: Tree, pt: ProtoType)(fallBack: (Tree, TyperState) => Tree)(implicit ctx: Context): Tree =
- fallBack(tree, ctx.typerState)
+ override def tryInsertApplyOrImplicit(tree: Tree, pt: ProtoType)(fallBack: => Tree)(implicit ctx: Context): Tree =
+ fallBack
override def completeAnnotations(mdef: untpd.MemberDef, sym: Symbol)(implicit ctx: Context): Unit = ()
diff --git a/compiler/src/dotty/tools/dotc/typer/RefChecks.scala b/compiler/src/dotty/tools/dotc/typer/RefChecks.scala
index 46bdbf3b3..3192546cd 100644
--- a/compiler/src/dotty/tools/dotc/typer/RefChecks.scala
+++ b/compiler/src/dotty/tools/dotc/typer/RefChecks.scala
@@ -18,7 +18,6 @@ import config.{ScalaVersion, NoScalaVersion}
import Decorators._
import typer.ErrorReporting._
import DenotTransformers._
-import ValueClasses.isDerivedValueClass
object RefChecks {
import tpd._
@@ -300,7 +299,9 @@ object RefChecks {
!member.isAnyOverride) {
// (*) Exclusion for default getters, fixes SI-5178. We cannot assign the Override flag to
// the default getter: one default getter might sometimes override, sometimes not. Example in comment on ticket.
- if (autoOverride(member))
+ // Also excluded under Scala2 mode are overrides of default methods of Java traits.
+ if (autoOverride(member) ||
+ other.owner.is(JavaTrait) && ctx.testScala2Mode("`override' modifier required when a Java 8 default method is re-implemented", member.pos))
member.setFlag(Override)
else if (member.owner != clazz && other.owner != clazz && !(other.owner derivesFrom member.owner))
emitOverrideError(
@@ -327,7 +328,8 @@ object RefChecks {
overrideError("needs to be a stable, immutable value")
} else if (member.is(ModuleVal) && !other.isRealMethod && !other.is(Deferred | Lazy)) {
overrideError("may not override a concrete non-lazy value")
- } else if (member.is(Lazy, butNot = Module) && !other.isRealMethod && !other.is(Lazy)) {
+ } else if (member.is(Lazy, butNot = Module) && !other.isRealMethod && !other.is(Lazy) &&
+ !ctx.testScala2Mode("may not override a non-lazy value", member.pos)) {
overrideError("may not override a non-lazy value")
} else if (other.is(Lazy) && !other.isRealMethod && !member.is(Lazy)) {
overrideError("must be declared lazy to override a lazy value")
@@ -688,39 +690,6 @@ object RefChecks {
}
}
- /** Verify classes extending AnyVal meet the requirements */
- private def checkDerivedValueClass(clazz: Symbol, stats: List[Tree])(implicit ctx: Context) = {
- def checkValueClassMember(stat: Tree) = stat match {
- case _: ValDef if !stat.symbol.is(ParamAccessor) =>
- ctx.error(s"value class may not define non-parameter field", stat.pos)
- case _: DefDef if stat.symbol.isConstructor =>
- ctx.error(s"value class may not define secondary constructor", stat.pos)
- case _: MemberDef | _: Import | EmptyTree =>
- // ok
- case _ =>
- ctx.error(s"value class may not contain initialization statements", stat.pos)
- }
- if (isDerivedValueClass(clazz)) {
- if (clazz.is(Trait))
- ctx.error("Only classes (not traits) are allowed to extend AnyVal", clazz.pos)
- if (clazz.is(Abstract))
- ctx.error("`abstract' modifier cannot be used with value classes", clazz.pos)
- if (!clazz.isStatic)
- ctx.error(s"value class may not be a ${if (clazz.owner.isTerm) "local class" else "member of another class"}", clazz.pos)
- else {
- val clParamAccessors = clazz.asClass.paramAccessors.filter(sym => sym.isTerm && !sym.is(Method))
- clParamAccessors match {
- case List(param) =>
- if (param.is(Mutable))
- ctx.error("value class parameter must not be a var", param.pos)
- case _ =>
- ctx.error("value class needs to have exactly one val parameter", clazz.pos)
- }
- }
- stats.foreach(checkValueClassMember)
- }
- }
-
type LevelAndIndex = immutable.Map[Symbol, (LevelInfo, Int)]
class OptLevelInfo extends DotClass {
@@ -836,7 +805,6 @@ class RefChecks extends MiniPhase { thisTransformer =>
checkParents(cls)
checkCompanionNameClashes(cls)
checkAllOverrides(cls)
- checkDerivedValueClass(cls, tree.body)
tree
} catch {
case ex: MergeError =>
diff --git a/compiler/src/dotty/tools/dotc/typer/TypeAssigner.scala b/compiler/src/dotty/tools/dotc/typer/TypeAssigner.scala
index ee2d68278..5c07b7bcf 100644
--- a/compiler/src/dotty/tools/dotc/typer/TypeAssigner.scala
+++ b/compiler/src/dotty/tools/dotc/typer/TypeAssigner.scala
@@ -189,9 +189,8 @@ trait TypeAssigner {
val where = if (ctx.owner.exists) s" from ${ctx.owner.enclosingClass}" else ""
val whyNot = new StringBuffer
alts foreach (_.isAccessibleFrom(pre, superAccess, whyNot))
- if (!tpe.isError)
- ctx.error(ex"$what cannot be accessed as a member of $pre$where.$whyNot", pos)
- ErrorType
+ if (tpe.isError) tpe
+ else errorType(ex"$what cannot be accessed as a member of $pre$where.$whyNot", pos)
}
}
else if (d.symbol is TypeParamAccessor)
@@ -215,17 +214,17 @@ trait TypeAssigner {
else if (site.derivesFrom(defn.DynamicClass) && !Dynamic.isDynamicMethod(name)) {
TryDynamicCallType
} else {
- if (!site.isErroneous) {
+ if (site.isErroneous) UnspecifiedErrorType
+ else {
def kind = if (name.isTypeName) "type" else "value"
def addendum =
if (site.derivesFrom(defn.DynamicClass)) "\npossible cause: maybe a wrong Dynamic method signature?"
else ""
- ctx.error(
+ errorType(
if (name == nme.CONSTRUCTOR) ex"$site does not have a constructor"
else NotAMember(site, name, kind),
pos)
}
- ErrorType
}
}
@@ -283,7 +282,9 @@ trait TypeAssigner {
def assignType(tree: untpd.This)(implicit ctx: Context) = {
val cls = qualifyingClass(tree, tree.qual.name, packageOK = false)
- tree.withType(cls.thisType)
+ tree.withType(
+ if (cls.isClass) cls.thisType
+ else errorType("not a legal qualifying class for this", tree.pos))
}
def assignType(tree: untpd.Super, qual: Tree, inConstrCall: Boolean, mixinClass: Symbol = NoSymbol)(implicit ctx: Context) = {
@@ -314,7 +315,8 @@ trait TypeAssigner {
val ownType = fn.tpe.widen match {
case fntpe @ MethodType(_, ptypes) =>
if (sameLength(ptypes, args) || ctx.phase.prev.relaxedTyping) fntpe.instantiate(args.tpes)
- else wrongNumberOfArgs(fn.tpe, "", fntpe.typeParams, args, tree.pos)
+ else
+ errorType(i"wrong number of arguments for $fntpe: ${fn.tpe}, expected: ${ptypes.length}, found: ${args.length}", tree.pos)
case t =>
errorType(i"${err.exprStr(fn)} does not take parameters", tree.pos)
}
@@ -369,7 +371,7 @@ trait TypeAssigner {
else {
val argTypes = args.tpes
if (sameLength(argTypes, paramNames) || ctx.phase.prev.relaxedTyping) pt.instantiate(argTypes)
- else wrongNumberOfArgs(fn.tpe, "type", pt.typeParams, args, tree.pos)
+ else wrongNumberOfTypeArgs(fn.tpe, pt.typeParams, args, tree.pos)
}
case _ =>
errorType(i"${err.exprStr(fn)} does not take type parameters", tree.pos)
@@ -462,7 +464,7 @@ trait TypeAssigner {
val ownType =
if (hasNamedArg(args)) (tycon.tpe /: args)(refineNamed)
else if (sameLength(tparams, args)) tycon.tpe.appliedTo(args.tpes)
- else wrongNumberOfArgs(tycon.tpe, "type", tparams, args, tree.pos)
+ else wrongNumberOfTypeArgs(tycon.tpe, tparams, args, tree.pos)
tree.withType(ownType)
}
diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala
index 9f5a942d6..a053a0b0d 100644
--- a/compiler/src/dotty/tools/dotc/typer/Typer.scala
+++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala
@@ -27,7 +27,7 @@ import EtaExpansion.etaExpand
import dotty.tools.dotc.transform.Erasure.Boxing
import util.Positions._
import util.common._
-import util.SourcePosition
+import util.{SourcePosition, Property}
import collection.mutable
import annotation.tailrec
import Implicits._
@@ -57,6 +57,8 @@ object Typer {
def assertPositioned(tree: untpd.Tree)(implicit ctx: Context) =
if (!tree.isEmpty && !tree.isInstanceOf[untpd.TypedSplice] && ctx.typerState.isGlobalCommittable)
assert(tree.pos.exists, s"position not set for $tree # ${tree.uniqueId}")
+
+ private val ExprOwner = new Property.Key[Symbol]
}
class Typer extends Namer with TypeAssigner with Applications with Implicits with Dynamic with Checking with Docstrings {
@@ -74,7 +76,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
* Note: It would be more proper to move importedFromRoot into typedIdent.
* We should check that this has no performance degradation, however.
*/
- private var importedFromRoot: Set[Symbol] = Set()
+ private var unimported: Set[Symbol] = Set()
/** Temporary data item for single call to typed ident:
* This symbol would be found under Scala2 mode, but is not
@@ -102,15 +104,6 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
*/
def error(msg: => Message, pos: Position) = ctx.error(msg, pos)
- /** Is this import a root import that has been shadowed by an explicit
- * import in the same program?
- */
- def isDisabled(imp: ImportInfo, site: Type): Boolean = {
- if (imp.isRootImport && (importedFromRoot contains site.termSymbol)) return true
- if (imp.hiddenRoot.exists) importedFromRoot += imp.hiddenRoot
- false
- }
-
/** Does this identifier appear as a constructor of a pattern? */
def isPatternConstr =
if (ctx.mode.isExpr && (ctx.outer.mode is Mode.Pattern))
@@ -188,32 +181,44 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
/** The type representing a named import with enclosing name when imported
* from given `site` and `selectors`.
*/
- def namedImportRef(site: Type, selectors: List[untpd.Tree])(implicit ctx: Context): Type = {
- def checkUnambiguous(found: Type) = {
- val other = namedImportRef(site, selectors.tail)
- if (other.exists && found.exists && (found != other))
- error(em"reference to `$name` is ambiguous; it is imported twice in ${ctx.tree}",
- tree.pos)
- found
- }
+ def namedImportRef(imp: ImportInfo)(implicit ctx: Context): Type = {
val Name = name.toTermName.decode
- selectors match {
+ def recur(selectors: List[untpd.Tree]): Type = selectors match {
case selector :: rest =>
+ def checkUnambiguous(found: Type) = {
+ val other = recur(selectors.tail)
+ if (other.exists && found.exists && (found != other))
+ error(em"reference to `$name` is ambiguous; it is imported twice in ${ctx.tree}",
+ tree.pos)
+ found
+ }
+
+ def selection(name: Name) =
+ if (imp.sym.isCompleting) {
+ ctx.warning(i"cyclic ${imp.sym}, ignored", tree.pos)
+ NoType
+ }
+ else if (unimported.nonEmpty && unimported.contains(imp.site.termSymbol))
+ NoType
+ else {
+ // Pass refctx so that any errors are reported in the context of the
+ // reference instead of the
+ checkUnambiguous(selectionType(imp.site, name, tree.pos)(refctx))
+ }
+
selector match {
case Thicket(fromId :: Ident(Name) :: _) =>
val Ident(from) = fromId
- val selName = if (name.isTypeName) from.toTypeName else from
- // Pass refctx so that any errors are reported in the context of the
- // reference instead of the context of the import.
- checkUnambiguous(selectionType(site, selName, tree.pos)(refctx))
+ selection(if (name.isTypeName) from.toTypeName else from)
case Ident(Name) =>
- checkUnambiguous(selectionType(site, name, tree.pos)(refctx))
+ selection(name)
case _ =>
- namedImportRef(site, rest)
+ recur(rest)
}
case nil =>
NoType
}
+ recur(imp.selectors)
}
/** The type representing a wildcard import with enclosing name when imported
@@ -222,7 +227,9 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
def wildImportRef(imp: ImportInfo)(implicit ctx: Context): Type = {
if (imp.isWildcardImport) {
val pre = imp.site
- if (!isDisabled(imp, pre) && !(imp.excluded contains name.toTermName) && name != nme.CONSTRUCTOR) {
+ if (!unimported.contains(pre.termSymbol) &&
+ !imp.excluded.contains(name.toTermName) &&
+ name != nme.CONSTRUCTOR) {
val denot = pre.member(name).accessibleFrom(pre)(refctx)
if (reallyExists(denot)) return pre.select(name, denot)
}
@@ -279,19 +286,27 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
if (result.exists) result
else { // find import
val curImport = ctx.importInfo
+ def updateUnimported() =
+ if (curImport.unimported.exists) unimported += curImport.unimported
if (ctx.owner.is(Package) && curImport != null && curImport.isRootImport && previous.exists)
previous // no more conflicts possible in this case
- else if (isPossibleImport(namedImport) && (curImport ne outer.importInfo) && !curImport.sym.isCompleting) {
- val namedImp = namedImportRef(curImport.site, curImport.selectors)
+ else if (isPossibleImport(namedImport) && (curImport ne outer.importInfo)) {
+ val namedImp = namedImportRef(curImport)
if (namedImp.exists)
findRef(checkNewOrShadowed(namedImp, namedImport), namedImport, ctx)(outer)
- else if (isPossibleImport(wildImport)) {
+ else if (isPossibleImport(wildImport) && !curImport.sym.isCompleting) {
val wildImp = wildImportRef(curImport)
if (wildImp.exists)
findRef(checkNewOrShadowed(wildImp, wildImport), wildImport, ctx)(outer)
- else loop(outer)
+ else {
+ updateUnimported()
+ loop(outer)
+ }
+ }
+ else {
+ updateUnimported()
+ loop(outer)
}
- else loop(outer)
}
else loop(outer)
}
@@ -311,11 +326,10 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
return typed(desugar.patternVar(tree), pt)
}
-
val rawType = {
- val saved1 = importedFromRoot
+ val saved1 = unimported
val saved2 = foundUnderScala2
- importedFromRoot = Set.empty
+ unimported = Set.empty
foundUnderScala2 = NoType
try {
var found = findRef(NoType, BindingPrec.nothingBound, NoContext)
@@ -329,7 +343,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
found
}
finally {
- importedFromRoot = saved1
+ unimported = saved1
foundUnderScala2 = saved2
}
}
@@ -337,10 +351,8 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
val ownType =
if (rawType.exists)
ensureAccessible(rawType, superAccess = false, tree.pos)
- else {
- error(new MissingIdent(tree, kind, name.show), tree.pos)
- ErrorType
- }
+ else
+ errorType(new MissingIdent(tree, kind, name.show), tree.pos)
val tree1 = ownType match {
case ownType: NamedType if !prefixIsElidable(ownType) =>
@@ -440,6 +452,11 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
tree.tpt match {
case templ: untpd.Template =>
import untpd._
+ templ.parents foreach {
+ case parent: RefTree =>
+ typedAheadImpl(parent, tree => inferTypeParams(typedType(tree), pt))
+ case _ =>
+ }
val x = tpnme.ANON_CLASS
val clsDef = TypeDef(x, templ).withFlags(Final)
typed(cpy.Block(tree)(clsDef :: Nil, New(Ident(x), Nil)), pt)
@@ -505,7 +522,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
case tref: TypeRef if !tref.symbol.isClass && !ctx.isAfterTyper =>
inferImplicit(defn.ClassTagType.appliedTo(tref),
EmptyTree, tpt1.pos)(ctx.retractMode(Mode.Pattern)) match {
- case SearchSuccess(arg, _, _) =>
+ case SearchSuccess(arg, _, _, _) =>
return typed(untpd.Apply(untpd.TypedSplice(arg), tree.expr), pt)
case _ =>
}
@@ -576,7 +593,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
}
def typedBlockStats(stats: List[untpd.Tree])(implicit ctx: Context): (Context, List[tpd.Tree]) =
- (index(stats), typedStats(stats, ctx.owner))
+ (indexAndAnnotate(stats), typedStats(stats, ctx.owner))
def typedBlock(tree: untpd.Block, pt: Type)(implicit ctx: Context) = track("typedBlock") {
val (exprCtx, stats1) = typedBlockStats(tree.stats)
@@ -646,9 +663,13 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
def typedFunction(tree: untpd.Function, pt: Type)(implicit ctx: Context) = track("typedFunction") {
val untpd.Function(args, body) = tree
- if (ctx.mode is Mode.Type)
+ if (ctx.mode is Mode.Type) {
+ val funCls =
+ if (tree.isInstanceOf[untpd.ImplicitFunction]) defn.ImplicitFunctionClass(args.length)
+ else defn.FunctionClass(args.length)
typed(cpy.AppliedTypeTree(tree)(
- untpd.TypeTree(defn.FunctionClass(args.length).typeRef), args :+ body), pt)
+ untpd.TypeTree(funCls.typeRef), args :+ body), pt)
+ }
else {
val params = args.asInstanceOf[List[untpd.ValDef]]
@@ -1009,7 +1030,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
def typedRefinedTypeTree(tree: untpd.RefinedTypeTree)(implicit ctx: Context): RefinedTypeTree = track("typedRefinedTypeTree") {
val tpt1 = if (tree.tpt.isEmpty) TypeTree(defn.ObjectType) else typedAheadType(tree.tpt)
- val refineClsDef = desugar.refinedTypeToClass(tpt1, tree.refinements)
+ val refineClsDef = desugar.refinedTypeToClass(tpt1, tree.refinements).withPos(tree.pos)
val refineCls = createSymbol(refineClsDef).asClass
val TypeDef(_, impl: Template) = typed(refineClsDef)
val refinements1 = impl.body
@@ -1038,7 +1059,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
if (hasNamedArg(args)) typedNamedArgs(args)
else {
if (args.length != tparams.length) {
- wrongNumberOfArgs(tpt1.tpe, "type", tparams, args, tree.pos)
+ wrongNumberOfTypeArgs(tpt1.tpe, tparams, args, tree.pos)
args = args.take(tparams.length)
}
def typedArg(arg: untpd.Tree, tparam: TypeParamInfo) = {
@@ -1058,7 +1079,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
def typedPolyTypeTree(tree: untpd.PolyTypeTree)(implicit ctx: Context): Tree = track("typedPolyTypeTree") {
val PolyTypeTree(tparams, body) = tree
- index(tparams)
+ indexAndAnnotate(tparams)
val tparams1 = tparams.mapconserve(typed(_).asInstanceOf[TypeDef])
val body1 = typedType(tree.body)
assignType(cpy.PolyTypeTree(tree)(tparams1, body1), tparams1, body1)
@@ -1121,7 +1142,17 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
def completeAnnotations(mdef: untpd.MemberDef, sym: Symbol)(implicit ctx: Context): Unit = {
// necessary to force annotation trees to be computed.
sym.annotations.foreach(_.ensureCompleted)
- val annotCtx = ctx.outersIterator.dropWhile(_.owner == sym).next
+ lazy val annotCtx = {
+ val c = ctx.outersIterator.dropWhile(_.owner == sym).next
+ c.property(ExprOwner) match {
+ case Some(exprOwner) if c.owner.isClass =>
+ // We need to evaluate annotation arguments in an expression context, since
+ // classes defined in a such arguments should not be entered into the
+ // enclosing class.
+ c.exprContext(mdef, exprOwner)
+ case _ => c
+ }
+ }
// necessary in order to mark the typed ahead annotations as definitely typed:
untpd.modsDeco(mdef).mods.annotations.foreach(typedAnnotation(_)(annotCtx))
}
@@ -1142,6 +1173,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
if (sym.is(Inline, butNot = DeferredOrParamAccessor))
checkInlineConformant(rhs1, em"right-hand side of inline $sym")
patchIfLazy(vdef1)
+ patchFinalVals(vdef1)
vdef1
}
@@ -1154,6 +1186,27 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
patch(Position(toUntyped(vdef).pos.start), "@volatile ")
}
+ /** Adds inline to final vals with idempotent rhs
+ *
+ * duplicating scalac behavior: for final vals that have rhs as constant, we do not create a field
+ * and instead return the value. This seemingly minor optimization has huge effect on initialization
+ * order and the values that can be observed during superconstructor call
+ *
+ * see remark about idempotency in PostTyper#normalizeTree
+ */
+ private def patchFinalVals(vdef: ValDef)(implicit ctx: Context): Unit = {
+ def isFinalInlinableVal(sym: Symbol): Boolean = {
+ sym.is(Final, butNot = Mutable) &&
+ isIdempotentExpr(vdef.rhs) /* &&
+ ctx.scala2Mode (stay compatible with Scala2 for now) */
+ }
+ val sym = vdef.symbol
+ sym.info match {
+ case info: ConstantType if isFinalInlinableVal(sym) && !ctx.settings.YnoInline.value => sym.setFlag(Inline)
+ case _ =>
+ }
+ }
+
def typedDefDef(ddef: untpd.DefDef, sym: Symbol)(implicit ctx: Context) = track("typedDefDef") {
val DefDef(name, tparams, vparamss, tpt, _) = ddef
completeAnnotations(ddef, sym)
@@ -1269,6 +1322,10 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
ctx.featureWarning(nme.dynamics.toString, "extension of type scala.Dynamic", isScala2Feature = true,
cls, isRequired, cdef.pos)
}
+
+ // check value class constraints
+ checkDerivedValueClass(cls, body1)
+
cdef1
// todo later: check that
@@ -1462,6 +1519,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
case tree: untpd.If => typedIf(tree, pt)
case tree: untpd.Function => typedFunction(tree, pt)
case tree: untpd.Closure => typedClosure(tree, pt)
+ case tree: untpd.Import => typedImport(tree, retrieveSym(tree))
case tree: untpd.Match => typedMatch(tree, pt)
case tree: untpd.Return => typedReturn(tree)
case tree: untpd.Try => typedTry(tree, pt)
@@ -1489,9 +1547,13 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
case _ => typedUnadapted(desugar(tree), pt)
}
- xtree match {
+ if (defn.isImplicitFunctionType(pt) &&
+ xtree.isTerm &&
+ !untpd.isImplicitClosure(xtree) &&
+ !ctx.isAfterTyper)
+ makeImplicitFunction(xtree, pt)
+ else xtree match {
case xtree: untpd.NameTree => typedNamed(encodeName(xtree), pt)
- case xtree: untpd.Import => typedImport(xtree, retrieveSym(xtree))
case xtree => typedUnnamed(xtree)
}
}
@@ -1500,6 +1562,14 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
protected def encodeName(tree: untpd.NameTree)(implicit ctx: Context): untpd.NameTree =
untpd.rename(tree, tree.name.encode)
+ protected def makeImplicitFunction(tree: untpd.Tree, pt: Type)(implicit ctx: Context): Tree = {
+ val defn.FunctionOf(formals, resType, true) = pt.dealias
+ val paramTypes = formals.map(fullyDefinedType(_, "implicit function parameter", tree.pos))
+ val ifun = desugar.makeImplicitFunction(paramTypes, tree)
+ typr.println(i"make implicit function $tree / $pt ---> $ifun")
+ typedUnadapted(ifun)
+ }
+
def typed(tree: untpd.Tree, pt: Type = WildcardType)(implicit ctx: Context): Tree = /*>|>*/ ctx.traceIndented (i"typing $tree", typr, show = true) /*<|<*/ {
assertPositioned(tree)
try adapt(typedUnadapted(tree, pt), pt, tree)
@@ -1540,7 +1610,11 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
case nil =>
buf.toList
}
- traverse(stats)
+ val localCtx = {
+ val exprOwnerOpt = if (exprOwner == ctx.owner) None else Some(exprOwner)
+ ctx.withProperty(ExprOwner, exprOwnerOpt)
+ }
+ traverse(stats)(localCtx)
}
/** Given an inline method `mdef`, the method rewritten so that its body
@@ -1580,23 +1654,52 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
}
}
- /** Add apply node or implicit conversions. Two strategies are tried, and the first
- * that is successful is picked. If neither of the strategies are successful, continues with
- * `fallBack`.
+ /** Is `pt` a prototype of an `apply` selection, or a parameterless function yielding one? */
+ def isApplyProto(pt: Type)(implicit ctx: Context): Boolean = pt match {
+ case pt: SelectionProto => pt.name == nme.apply
+ case pt: FunProto => pt.args.isEmpty && isApplyProto(pt.resultType)
+ case pt: IgnoredProto => isApplyProto(pt.ignored)
+ case _ => false
+ }
+
+ /** Potentially add apply node or implicit conversions. Before trying either,
+ * if the function is applied to an empty parameter list (), we try
+ *
+ * 0th strategy: If `tree` overrides a nullary method, mark the prototype
+ * so that the argument is dropped and return `tree` itself.
+ *
+ * After that, two strategies are tried, and the first that is successful is picked.
+ * If neither of the strategies are successful, continues with`fallBack`.
*
* 1st strategy: Try to insert `.apply` so that the result conforms to prototype `pt`.
+ * This strategy is not tried if the prototype represents already
+ * another `.apply` or `.apply()` selection.
+ *
* 2nd strategy: If tree is a select `qual.name`, try to insert an implicit conversion
* around the qualifier part `qual` so that the result conforms to the expected type
* with wildcard result type.
*/
- def tryInsertApplyOrImplicit(tree: Tree, pt: ProtoType)(fallBack: (Tree, TyperState) => Tree)(implicit ctx: Context): Tree =
- tryEither { implicit ctx =>
+ def tryInsertApplyOrImplicit(tree: Tree, pt: ProtoType)(fallBack: => Tree)(implicit ctx: Context): Tree = {
+
+ def tryApply(implicit ctx: Context) = {
val sel = typedSelect(untpd.Select(untpd.TypedSplice(tree), nme.apply), pt)
if (sel.tpe.isError) sel else adapt(sel, pt)
- } { (failedTree, failedState) =>
- tryInsertImplicitOnQualifier(tree, pt).getOrElse(fallBack(failedTree, failedState))
}
+ def tryImplicit =
+ tryInsertImplicitOnQualifier(tree, pt).getOrElse(fallBack)
+
+ pt match {
+ case pt @ FunProto(Nil, _, _)
+ if tree.symbol.allOverriddenSymbols.exists(_.info.isNullaryMethod) =>
+ pt.markAsDropped()
+ tree
+ case _ =>
+ if (isApplyProto(pt)) tryImplicit
+ else tryEither(tryApply(_))((_, _) => tryImplicit)
+ }
+ }
+
/** If this tree is a select node `qual.name`, try to insert an implicit conversion
* `c` around `qual` so that `c(qual).name` conforms to `pt`.
*/
@@ -1688,7 +1791,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
def hasEmptyParams(denot: SingleDenotation) = denot.info.paramTypess == ListOfNil
pt match {
case pt: FunProto =>
- tryInsertApplyOrImplicit(tree, pt)((_, _) => noMatches)
+ tryInsertApplyOrImplicit(tree, pt)(noMatches)
case _ =>
if (altDenots exists (_.info.paramTypess == ListOfNil))
typed(untpd.Apply(untpd.TypedSplice(tree), Nil), pt)
@@ -1727,7 +1830,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
case Apply(_, _) => " more"
case _ => ""
}
- (_, _) => errorTree(tree, em"$methodStr does not take$more parameters")
+ errorTree(tree, em"$methodStr does not take$more parameters")
}
}
@@ -1828,9 +1931,18 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
missingArgs
case _ =>
ctx.typeComparer.GADTused = false
- if (ctx.mode is Mode.Pattern) {
+ if (defn.isImplicitFunctionClass(wtp.underlyingClassRef(refinementOK = false).classSymbol) &&
+ !untpd.isImplicitClosure(tree) &&
+ !isApplyProto(pt) &&
+ !ctx.isAfterTyper) {
+ typr.println("insert apply on implicit $tree")
+ typed(untpd.Select(untpd.TypedSplice(tree), nme.apply), pt)
+ }
+ else if (ctx.mode is Mode.Pattern) {
tree match {
- case _: RefTree | _: Literal if !isVarPattern(tree) =>
+ case _: RefTree | _: Literal
+ if !isVarPattern(tree) &&
+ !(tree.tpe <:< pt)(ctx.addMode(Mode.GADTflexible)) =>
checkCanEqual(pt, wtp, tree.pos)(ctx.retractMode(Mode.Pattern))
case _ =>
}
@@ -1899,7 +2011,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
}
// try an implicit conversion
inferView(tree, pt) match {
- case SearchSuccess(inferred, _, _) =>
+ case SearchSuccess(inferred, _, _, _) =>
adapt(inferred, pt)
case failure: SearchFailure =>
if (pt.isInstanceOf[ProtoType] && !failure.isInstanceOf[AmbiguousImplicits]) tree
@@ -1915,10 +2027,25 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
else err.typeMismatch(tree1, pt)
}
+ /** If tree has an error type but no errors are reported yet, issue
+ * the error message stored in the type.
+ * One way this can happen is if implicit search causes symbols and types
+ * to be completed. The types are stored by `typedAhead` so that they can be
+ * retrieved later and thus avoid duplication of typechecking work.
+ * But if the implicit search causing the `typedAhead` fails locally but
+ * another alternative succeeds we can be left with an ErrorType in the
+ * tree that went unreported. A scenario where this happens is i1802.scala.
+ */
+ def ensureReported(tp: Type) = tp match {
+ case err: ErrorType if !ctx.reporter.hasErrors => ctx.error(err.msg, tree.pos)
+ case _ =>
+ }
+
tree match {
case _: MemberDef | _: PackageDef | _: Import | _: WithoutTypeOrPos[_] => tree
case _ => tree.tpe.widen match {
- case _: ErrorType =>
+ case tp: FlexType =>
+ ensureReported(tp)
tree
case ref: TermRef =>
pt match {
@@ -1932,21 +2059,19 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
if (pt.isInstanceOf[PolyProto]) tree
else {
var typeArgs = tree match {
- case Select(qual, nme.CONSTRUCTOR) => qual.tpe.widenDealias.argTypesLo
+ case Select(qual, nme.CONSTRUCTOR) => qual.tpe.widenDealias.argTypesLo.map(TypeTree)
case _ => Nil
}
if (typeArgs.isEmpty) typeArgs = constrained(poly, tree)._2
convertNewGenericArray(
- adaptInterpolated(tree.appliedToTypes(typeArgs), pt, original))
+ adaptInterpolated(tree.appliedToTypeTrees(typeArgs), pt, original))
}
case wtp =>
pt match {
case pt: FunProto =>
adaptToArgs(wtp, pt)
case pt: PolyProto =>
- tryInsertApplyOrImplicit(tree, pt) {
- (_, _) => tree // error will be reported in typedTypeApply
- }
+ tryInsertApplyOrImplicit(tree, pt)(tree) // error will be reported in typedTypeApply
case _ =>
if (ctx.mode is Mode.Type) adaptType(tree.tpe)
else adaptNoArgs(wtp)
diff --git a/compiler/src/dotty/tools/dotc/util/Chars.scala b/compiler/src/dotty/tools/dotc/util/Chars.scala
index bae3b4732..6f95b87c4 100644
--- a/compiler/src/dotty/tools/dotc/util/Chars.scala
+++ b/compiler/src/dotty/tools/dotc/util/Chars.scala
@@ -6,7 +6,6 @@ package dotty.tools.dotc
package util
import scala.annotation.switch
-import java.lang.{ Character => JCharacter }
import java.lang.{Character => JCharacter}
import java.lang.Character.LETTER_NUMBER
import java.lang.Character.LOWERCASE_LETTER
@@ -66,16 +65,16 @@ object Chars {
/** Can character start an alphanumeric Scala identifier? */
def isIdentifierStart(c: Char): Boolean =
- (c == '_') || (c == '$') || Character.isUnicodeIdentifierStart(c)
+ (c == '_') || (c == '$') || JCharacter.isUnicodeIdentifierStart(c)
/** Can character form part of an alphanumeric Scala identifier? */
def isIdentifierPart(c: Char) =
- (c == '$') || Character.isUnicodeIdentifierPart(c)
+ (c == '$') || JCharacter.isUnicodeIdentifierPart(c)
/** Is character a math or other symbol in Unicode? */
def isSpecial(c: Char) = {
- val chtp = Character.getType(c)
- chtp == Character.MATH_SYMBOL.toInt || chtp == Character.OTHER_SYMBOL.toInt
+ val chtp = JCharacter.getType(c)
+ chtp == JCharacter.MATH_SYMBOL.toInt || chtp == JCharacter.OTHER_SYMBOL.toInt
}
private final val otherLetters = Set[Char]('\u0024', '\u005F') // '$' and '_'
diff --git a/compiler/test/dotc/scala-collections.blacklist b/compiler/test/dotc/scala-collections.blacklist
new file mode 100644
index 000000000..321814ab0
--- /dev/null
+++ b/compiler/test/dotc/scala-collections.blacklist
@@ -0,0 +1,83 @@
+## Errors having to do with bootstrap
+
+../scala-scala/src/library/scala/Function1.scala
+../scala-scala/src/library/scala/Function2.scala
+# Cyclic reference because of @specialized annotation
+
+
+## Errors having to do with deep subtypes
+
+../scala-scala/src/library/scala/collection/generic/ParSetFactory.scala
+# This gives a deep subtype violation when run with the rest of the whitelist.
+# Works without -Yno-deep-subtypes, though.
+
+../scala-scala/src/library/scala/collection/parallel/mutable/ParMap.scala
+# -Yno-deep-subtypes fails
+
+../scala-scala/src/library/scala/collection/parallel/ParMap.scala
+# -Yno-deep-subtypes fails
+
+../scala-scala/src/library/scala/collection/parallel/ParMapLike.scala
+# -Yno-deep-subtypes fails
+
+
+
+## Ycheck failures, presumably linked to TailCalls
+
+../scala-scala/src/library/scala/collection/parallel/ParIterableLike.scala
+# -Ycheck:classOf fails
+
+../scala-scala/src/library/scala/collection/parallel/ParSeqLike.scala
+# -Ycheck:classOf fails
+
+../scala-scala/src/library/scala/util/control/TailCalls.scala
+# -Ycheck:classOf fails
+
+
+
+## Errors having to do with unavailable APIs or language features:
+
+../scala-scala/src/library/scala/reflect/ClassManifestDeprecatedApis.scala
+# 51 | import Manifest._
+# | ^^^^^^^^
+# | not found: Manifest
+
+../scala-scala/src/library/scala/reflect/ClassTag.scala
+# 124 | val Short : ClassTag[scala.Short] = Manifest.Short
+# | ^^^^^^^^
+# | not found: Manifest
+
+../scala-scala/src/library/scala/reflect/Manifest.scala
+# 104 | private def readResolve(): Any = Manifest.Short
+# | ^^^^^^^^
+# | not found: Manifest
+
+../scala-scala/src/library/scala/text/Document.scala
+# Lots of type errors for pattern matches, having to do with the fact
+# that Document contains a :: method without corresponding extractor,
+# but still wants to extract lists using ::. We won't support that.
+# Since Document should have been removed already, let's ignore it.
+
+../scala-scala/src/library/scala/AnyVal.scala
+# 55 |abstract class AnyVal extends Any {
+# |^
+# |illegal redefinition of standard class AnyVal
+# (This is intended)
+
+../scala-scala/src/library/scala/collection/parallel/Tasks.scala
+# java.lang.StackOverflowError
+
+../scala-scala/src/library/scala/reflect/package.scala
+# 63 | private[scala] def materializeClassTag[T](): ClassTag[T] = macro ???
+# | ^^^^^
+# | not found: macro
+
+../scala-scala/src/library/scala/StringContext.scala
+# 168 | def f[A >: Any](args: A*): String = macro ???
+# | ^^^^^
+# | not found: macro
+
+../scala-scala/src/library/scala/util/control/Exception.scala
+# 51 | implicit def throwableSubtypeToCatcher[Ex <: Throwable: ClassTag, T](pf: PartialFunction[Ex, T]) =
+# | ^
+# | cyclic reference involving method mkCatcher
diff --git a/compiler/test/dotc/scala-collections.whitelist b/compiler/test/dotc/scala-collections.whitelist
index bb62b260a..57c71d647 100644
--- a/compiler/test/dotc/scala-collections.whitelist
+++ b/compiler/test/dotc/scala-collections.whitelist
@@ -7,6 +7,8 @@
../scala-scala/src/library/scala/runtime/RichInt.scala
../scala-scala/src/library/scala/runtime/RichLong.scala
../scala-scala/src/library/scala/runtime/RichShort.scala
+../scala-scala/src/library/scala/runtime/Tuple2Zipped.scala
+../scala-scala/src/library/scala/runtime/Tuple3Zipped.scala
../scala-scala/src/library/scala/Array.scala
../scala-scala/src/library/scala/NotImplementedError.scala
../scala-scala/src/library/scala/AnyValCompanion.scala
@@ -62,6 +64,7 @@
../scala-scala/src/library/scala/Serializable.scala
../scala-scala/src/library/scala/Specializable.scala
../scala-scala/src/library/scala/Symbol.scala
+#../scala-scala/src/library/scala/StringContext.scala
../scala-scala/src/library/scala/UninitializedError.scala
../scala-scala/src/library/scala/UninitializedFieldError.scala
../scala-scala/src/library/scala/collection/IndexedSeqOptimized.scala
@@ -86,6 +89,14 @@
../scala-scala/src/library/scala/collection/mutable/BufferLike.scala
../scala-scala/src/library/scala/collection/mutable/ArrayBuilder.scala
+../scala-scala/src/library/scala/collection/mutable/ObservableBuffer.scala
+../scala-scala/src/library/scala/collection/mutable/DefaultEntry.scala
+../scala-scala/src/library/scala/collection/mutable/LinkedHashMap.scala
+../scala-scala/src/library/scala/collection/mutable/ObservableMap.scala
+../scala-scala/src/library/scala/collection/mutable/ObservableSet.scala
+../scala-scala/src/library/scala/collection/mutable/SynchronizedQueue.scala
+../scala-scala/src/library/scala/collection/mutable/UnrolledBuffer.scala
+../scala-scala/src/library/scala/collection/mutable/SynchronizedBuffer.scala
../scala-scala/src/library/scala/collection/immutable/Stack.scala
../scala-scala/src/library/scala/collection/immutable/StringLike.scala
@@ -264,10 +275,9 @@
../scala-scala/src/library/scala/collection/generic/SetFactory.scala
../scala-scala/src/library/scala/collection/generic/ParFactory.scala
-# https://github.com/lampepfl/dotty/issues/974 -> @smarter
../scala-scala/src/library/scala/collection/generic/MutableSortedSetFactory.scala
-# cyclic reference, maybe related to #974 -> @smarter
+# deep subtype
#../scala-scala/src/library/scala/collection/generic/ParSetFactory.scala
../scala-scala/src/library/scala/collection/generic/OrderedTraversableFactory.scala
@@ -280,3 +290,339 @@
../scala-scala/src/library/scala/collection/generic/Subtractable.scala
../scala-scala/src/library/scala/collection/generic/TraversableFactory.scala
../scala-scala/src/library/scala/collection/generic/package.scala
+
+../scala-scala/src/library/scala/util/Try.scala
+
+#../scala-scala/src/library/scala/util/control/Exception.scala
+../scala-scala/src/library/scala/util/control/Breaks.scala
+../scala-scala/src/library/scala/util/control/ControlThrowable.scala
+../scala-scala/src/library/scala/util/control/NonFatal.scala
+../scala-scala/src/library/scala/util/control/NoStackTrace.scala
+../scala-scala/src/library/scala/util/DynamicVariable.scala
+../scala-scala/src/library/scala/util/Either.scala
+../scala-scala/src/library/scala/util/hashing/Hashing.scala
+../scala-scala/src/library/scala/util/hashing/ByteswapHashing.scala
+../scala-scala/src/library/scala/util/hashing/MurmurHash3.scala
+../scala-scala/src/library/scala/util/hashing/package.scala
+../scala-scala/src/library/scala/util/matching/Regex.scala
+../scala-scala/src/library/scala/util/MurmurHash.scala
+../scala-scala/src/library/scala/util/Properties.scala
+../scala-scala/src/library/scala/util/Random.scala
+../scala-scala/src/library/scala/util/Sorting.scala
+
+../scala-scala/src/library/scala/collection/mutable/AnyRefMap.scala
+../scala-scala/src/library/scala/collection/mutable/ArrayBuffer.scala
+../scala-scala/src/library/scala/collection/mutable/ArrayLike.scala
+../scala-scala/src/library/scala/collection/mutable/ArrayOps.scala
+../scala-scala/src/library/scala/collection/mutable/ArraySeq.scala
+../scala-scala/src/library/scala/collection/mutable/ArrayStack.scala
+../scala-scala/src/library/scala/collection/mutable/AVLTree.scala
+../scala-scala/src/library/scala/collection/mutable/BitSet.scala
+../scala-scala/src/library/scala/collection/mutable/Buffer.scala
+../scala-scala/src/library/scala/collection/mutable/BufferProxy.scala
+../scala-scala/src/library/scala/collection/mutable/Cloneable.scala
+../scala-scala/src/library/scala/collection/mutable/DefaultMapModel.scala
+../scala-scala/src/library/scala/collection/mutable/DoubleLinkedList.scala
+../scala-scala/src/library/scala/collection/mutable/DoubleLinkedListLike.scala
+../scala-scala/src/library/scala/collection/mutable/FlatHashTable.scala
+../scala-scala/src/library/scala/collection/mutable/HashEntry.scala
+../scala-scala/src/library/scala/collection/mutable/HashMap.scala
+../scala-scala/src/library/scala/collection/mutable/HashSet.scala
+../scala-scala/src/library/scala/collection/mutable/HashTable.scala
+../scala-scala/src/library/scala/collection/mutable/History.scala
+../scala-scala/src/library/scala/collection/mutable/ImmutableSetAdaptor.scala
+../scala-scala/src/library/scala/collection/mutable/IndexedSeqLike.scala
+../scala-scala/src/library/scala/collection/mutable/IndexedSeqOptimized.scala
+../scala-scala/src/library/scala/collection/mutable/Iterable.scala
+../scala-scala/src/library/scala/collection/mutable/LazyBuilder.scala
+../scala-scala/src/library/scala/collection/mutable/LinearSeq.scala
+../scala-scala/src/library/scala/collection/mutable/LinkedEntry.scala
+../scala-scala/src/library/scala/collection/mutable/LinkedHashSet.scala
+../scala-scala/src/library/scala/collection/mutable/LinkedList.scala
+../scala-scala/src/library/scala/collection/mutable/LinkedListLike.scala
+../scala-scala/src/library/scala/collection/mutable/ListMap.scala
+../scala-scala/src/library/scala/collection/mutable/LongMap.scala
+../scala-scala/src/library/scala/collection/mutable/Map.scala
+../scala-scala/src/library/scala/collection/mutable/MapBuilder.scala
+../scala-scala/src/library/scala/collection/mutable/MapLike.scala
+../scala-scala/src/library/scala/collection/mutable/MapProxy.scala
+../scala-scala/src/library/scala/collection/mutable/MultiMap.scala
+../scala-scala/src/library/scala/collection/mutable/MutableList.scala
+../scala-scala/src/library/scala/collection/mutable/OpenHashMap.scala
+../scala-scala/src/library/scala/collection/mutable/PriorityQueue.scala
+../scala-scala/src/library/scala/collection/mutable/PriorityQueueProxy.scala
+../scala-scala/src/library/scala/collection/mutable/Publisher.scala
+../scala-scala/src/library/scala/collection/mutable/Queue.scala
+../scala-scala/src/library/scala/collection/mutable/QueueProxy.scala
+../scala-scala/src/library/scala/collection/mutable/ResizableArray.scala
+../scala-scala/src/library/scala/collection/mutable/RevertibleHistory.scala
+../scala-scala/src/library/scala/collection/mutable/Seq.scala
+../scala-scala/src/library/scala/collection/mutable/SeqLike.scala
+../scala-scala/src/library/scala/collection/mutable/Set.scala
+../scala-scala/src/library/scala/collection/mutable/SetBuilder.scala
+../scala-scala/src/library/scala/collection/mutable/SetLike.scala
+../scala-scala/src/library/scala/collection/mutable/SetProxy.scala
+../scala-scala/src/library/scala/collection/mutable/SortedSet.scala
+../scala-scala/src/library/scala/collection/mutable/Stack.scala
+../scala-scala/src/library/scala/collection/mutable/StackProxy.scala
+../scala-scala/src/library/scala/collection/mutable/StringBuilder.scala
+../scala-scala/src/library/scala/collection/mutable/Subscriber.scala
+../scala-scala/src/library/scala/collection/mutable/SynchronizedMap.scala
+../scala-scala/src/library/scala/collection/mutable/SynchronizedPriorityQueue.scala
+../scala-scala/src/library/scala/collection/mutable/SynchronizedSet.scala
+../scala-scala/src/library/scala/collection/mutable/SynchronizedStack.scala
+../scala-scala/src/library/scala/collection/mutable/Traversable.scala
+../scala-scala/src/library/scala/collection/mutable/TreeSet.scala
+../scala-scala/src/library/scala/collection/mutable/Undoable.scala
+../scala-scala/src/library/scala/collection/mutable/WeakHashMap.scala
+../scala-scala/src/library/scala/collection/mutable/ImmutableMapAdaptor.scala
+
+../scala-scala/src/library/scala/collection/convert/DecorateAsJava.scala
+../scala-scala/src/library/scala/collection/convert/DecorateAsScala.scala
+../scala-scala/src/library/scala/collection/convert/Decorators.scala
+../scala-scala/src/library/scala/collection/convert/package.scala
+../scala-scala/src/library/scala/collection/convert/WrapAsJava.scala
+../scala-scala/src/library/scala/collection/convert/WrapAsScala.scala
+../scala-scala/src/library/scala/collection/convert/Wrappers.scala
+
+../scala-scala/src/library/scala/collection/concurrent/Map.scala
+../scala-scala/src/library/scala/collection/concurrent/TrieMap.scala
+
+../scala-scala/src/library/scala/collection/parallel/immutable/package.scala
+../scala-scala/src/library/scala/collection/parallel/immutable/ParHashMap.scala
+../scala-scala/src/library/scala/collection/parallel/immutable/ParHashSet.scala
+../scala-scala/src/library/scala/collection/parallel/immutable/ParIterable.scala
+../scala-scala/src/library/scala/collection/parallel/immutable/ParMap.scala
+../scala-scala/src/library/scala/collection/parallel/immutable/ParRange.scala
+../scala-scala/src/library/scala/collection/parallel/immutable/ParSeq.scala
+../scala-scala/src/library/scala/collection/parallel/immutable/ParSet.scala
+../scala-scala/src/library/scala/collection/parallel/immutable/ParVector.scala
+
+../scala-scala/src/library/scala/compat/Platform.scala
+
+../scala-scala/src/library/scala/sys/package.scala
+../scala-scala/src/library/scala/sys/SystemProperties.scala
+../scala-scala/src/library/scala/sys/Prop.scala
+../scala-scala/src/library/scala/sys/PropImpl.scala
+../scala-scala/src/library/scala/sys/BooleanProp.scala
+../scala-scala/src/library/scala/sys/ShutdownHookThread.scala
+../scala-scala/src/library/scala/sys/process/BasicIO.scala
+../scala-scala/src/library/scala/sys/process/package.scala
+../scala-scala/src/library/scala/sys/process/Process.scala
+../scala-scala/src/library/scala/sys/process/ProcessBuilder.scala
+../scala-scala/src/library/scala/sys/process/ProcessBuilderImpl.scala
+../scala-scala/src/library/scala/sys/process/ProcessImpl.scala
+../scala-scala/src/library/scala/sys/process/ProcessIO.scala
+../scala-scala/src/library/scala/sys/process/ProcessLogger.scala
+
+../scala-scala/src/library/scala/beans/BeanDescription.scala
+../scala-scala/src/library/scala/beans/BeanDisplayName.scala
+../scala-scala/src/library/scala/beans/BeanInfo.scala
+../scala-scala/src/library/scala/beans/BeanInfoSkip.scala
+../scala-scala/src/library/scala/beans/BeanProperty.scala
+../scala-scala/src/library/scala/beans/BooleanBeanProperty.scala
+../scala-scala/src/library/scala/beans/ScalaBeanInfo.scala
+
+../scala-scala/src/library/scala/io/AnsiColor.scala
+../scala-scala/src/library/scala/io/Codec.scala
+../scala-scala/src/library/scala/io/Position.scala
+../scala-scala/src/library/scala/io/StdIn.scala
+../scala-scala/src/library/scala/io/BufferedSource.scala
+../scala-scala/src/library/scala/io/Source.scala
+
+../scala-scala/src/library/scala/math/BigDecimal.scala
+../scala-scala/src/library/scala/math/BigInt.scala
+../scala-scala/src/library/scala/math/PartiallyOrdered.scala
+
+../scala-scala/src/library/scala/ref/PhantomReference.scala
+../scala-scala/src/library/scala/ref/Reference.scala
+../scala-scala/src/library/scala/ref/ReferenceQueue.scala
+../scala-scala/src/library/scala/ref/ReferenceWrapper.scala
+../scala-scala/src/library/scala/ref/SoftReference.scala
+../scala-scala/src/library/scala/ref/WeakReference.scala
+
+../scala-scala/src/library/scala/reflect/macros/internal/macroImpl.scala
+../scala-scala/src/library/scala/reflect/NoManifest.scala
+../scala-scala/src/library/scala/reflect/OptManifest.scala
+../scala-scala/src/library/scala/reflect/NameTransformer.scala
+#../scala-scala/src/library/scala/reflect/package.scala
+
+../scala-scala/src/library/scala/Responder.scala
+
+../scala-scala/src/library/scala/collection/script/Location.scala
+../scala-scala/src/library/scala/collection/script/Message.scala
+../scala-scala/src/library/scala/collection/script/Scriptable.scala
+
+../scala-scala/src/library/scala/concurrent/package.scala
+../scala-scala/src/library/scala/concurrent/Future.scala
+../scala-scala/src/library/scala/concurrent/Awaitable.scala
+../scala-scala/src/library/scala/concurrent/BatchingExecutor.scala
+../scala-scala/src/library/scala/concurrent/BlockContext.scala
+../scala-scala/src/library/scala/concurrent/Channel.scala
+../scala-scala/src/library/scala/concurrent/DelayedLazyVal.scala
+../scala-scala/src/library/scala/concurrent/duration/Deadline.scala
+../scala-scala/src/library/scala/concurrent/duration/Duration.scala
+../scala-scala/src/library/scala/concurrent/duration/DurationConversions.scala
+../scala-scala/src/library/scala/concurrent/duration/package.scala
+../scala-scala/src/library/scala/concurrent/ExecutionContext.scala
+../scala-scala/src/library/scala/concurrent/FutureTaskRunner.scala
+../scala-scala/src/library/scala/concurrent/impl/Future.scala
+../scala-scala/src/library/scala/concurrent/impl/Promise.scala
+../scala-scala/src/library/scala/concurrent/JavaConversions.scala
+../scala-scala/src/library/scala/concurrent/Lock.scala
+../scala-scala/src/library/scala/concurrent/ManagedBlocker.scala
+../scala-scala/src/library/scala/concurrent/Promise.scala
+../scala-scala/src/library/scala/concurrent/SyncVar.scala
+../scala-scala/src/library/scala/concurrent/TaskRunner.scala
+../scala-scala/src/library/scala/concurrent/ThreadPoolRunner.scala
+../scala-scala/src/library/scala/concurrent/SyncChannel.scala
+../scala-scala/src/library/scala/concurrent/impl/ExecutionContextImpl.scala
+
+../scala-scala/src/library/scala/collection/parallel/package.scala
+../scala-scala/src/library/scala/collection/parallel/ParIterable.scala
+#../scala-scala/src/library/scala/collection/parallel/ParMap.scala
+#../scala-scala/src/library/scala/collection/parallel/ParMapLike.scala
+#../scala-scala/src/library/scala/collection/parallel/ParIterableLike.scala
+#../scala-scala/src/library/scala/collection/parallel/ParSeqLike.scala
+../scala-scala/src/library/scala/collection/parallel/Combiner.scala
+../scala-scala/src/library/scala/collection/parallel/mutable/LazyCombiner.scala
+../scala-scala/src/library/scala/collection/parallel/mutable/ResizableParArrayCombiner.scala
+../scala-scala/src/library/scala/collection/parallel/RemainsIterator.scala
+../scala-scala/src/library/scala/collection/parallel/mutable/package.scala
+../scala-scala/src/library/scala/collection/parallel/mutable/ParFlatHashTable.scala
+../scala-scala/src/library/scala/collection/parallel/mutable/ParHashMap.scala
+../scala-scala/src/library/scala/collection/parallel/mutable/ParHashSet.scala
+../scala-scala/src/library/scala/collection/parallel/mutable/ParHashTable.scala
+../scala-scala/src/library/scala/collection/parallel/mutable/ParIterable.scala
+../scala-scala/src/library/scala/collection/parallel/mutable/ParMapLike.scala
+../scala-scala/src/library/scala/collection/parallel/mutable/ParSeq.scala
+../scala-scala/src/library/scala/collection/parallel/mutable/ParSet.scala
+../scala-scala/src/library/scala/collection/parallel/mutable/ParSetLike.scala
+../scala-scala/src/library/scala/collection/parallel/mutable/ParTrieMap.scala
+../scala-scala/src/library/scala/collection/parallel/mutable/UnrolledParArrayCombiner.scala
+../scala-scala/src/library/scala/collection/parallel/mutable/ParArray.scala
+#../scala-scala/src/library/scala/collection/parallel/mutable/ParMap.scala
+../scala-scala/src/library/scala/collection/parallel/ParSeq.scala
+../scala-scala/src/library/scala/collection/parallel/ParSet.scala
+../scala-scala/src/library/scala/collection/parallel/ParSetLike.scala
+../scala-scala/src/library/scala/collection/parallel/PreciseSplitter.scala
+../scala-scala/src/library/scala/collection/parallel/Splitter.scala
+../scala-scala/src/library/scala/collection/parallel/TaskSupport.scala
+#../scala-scala/src/library/scala/collection/parallel/Tasks.scala
+
+../scala-scala/src/library/scala/Console.scala
+../scala-scala/src/library/scala/Enumeration.scala
+
+../scala-scala/src/library/scala/annotation/Annotation.scala
+../scala-scala/src/library/scala/annotation/bridge.scala
+../scala-scala/src/library/scala/annotation/ClassfileAnnotation.scala
+../scala-scala/src/library/scala/annotation/compileTimeOnly.scala
+../scala-scala/src/library/scala/annotation/elidable.scala
+../scala-scala/src/library/scala/annotation/implicitNotFound.scala
+../scala-scala/src/library/scala/annotation/meta/beanGetter.scala
+../scala-scala/src/library/scala/annotation/meta/beanSetter.scala
+../scala-scala/src/library/scala/annotation/meta/companionClass.scala
+../scala-scala/src/library/scala/annotation/meta/companionMethod.scala
+../scala-scala/src/library/scala/annotation/meta/companionObject.scala
+../scala-scala/src/library/scala/annotation/meta/field.scala
+../scala-scala/src/library/scala/annotation/meta/getter.scala
+../scala-scala/src/library/scala/annotation/meta/languageFeature.scala
+../scala-scala/src/library/scala/annotation/meta/package.scala
+../scala-scala/src/library/scala/annotation/meta/param.scala
+../scala-scala/src/library/scala/annotation/meta/setter.scala
+../scala-scala/src/library/scala/annotation/migration.scala
+../scala-scala/src/library/scala/annotation/StaticAnnotation.scala
+../scala-scala/src/library/scala/annotation/strictfp.scala
+../scala-scala/src/library/scala/annotation/switch.scala
+../scala-scala/src/library/scala/annotation/tailrec.scala
+../scala-scala/src/library/scala/annotation/TypeConstraint.scala
+../scala-scala/src/library/scala/annotation/unchecked/uncheckedStable.scala
+../scala-scala/src/library/scala/annotation/unchecked/uncheckedVariance.scala
+../scala-scala/src/library/scala/annotation/unspecialized.scala
+../scala-scala/src/library/scala/annotation/varargs.scala
+
+../scala-scala/src/library/scala/runtime/AbstractFunction0.scala
+../scala-scala/src/library/scala/runtime/AbstractFunction1.scala
+../scala-scala/src/library/scala/runtime/AbstractFunction10.scala
+../scala-scala/src/library/scala/runtime/AbstractFunction11.scala
+../scala-scala/src/library/scala/runtime/AbstractFunction12.scala
+../scala-scala/src/library/scala/runtime/AbstractFunction13.scala
+../scala-scala/src/library/scala/runtime/AbstractFunction14.scala
+../scala-scala/src/library/scala/runtime/AbstractFunction15.scala
+../scala-scala/src/library/scala/runtime/AbstractFunction16.scala
+../scala-scala/src/library/scala/runtime/AbstractFunction17.scala
+../scala-scala/src/library/scala/runtime/AbstractFunction18.scala
+../scala-scala/src/library/scala/runtime/AbstractFunction19.scala
+../scala-scala/src/library/scala/runtime/AbstractFunction2.scala
+../scala-scala/src/library/scala/runtime/AbstractFunction20.scala
+../scala-scala/src/library/scala/runtime/AbstractFunction21.scala
+../scala-scala/src/library/scala/runtime/AbstractFunction22.scala
+../scala-scala/src/library/scala/runtime/AbstractFunction3.scala
+../scala-scala/src/library/scala/runtime/AbstractFunction4.scala
+../scala-scala/src/library/scala/runtime/AbstractFunction5.scala
+../scala-scala/src/library/scala/runtime/AbstractFunction6.scala
+../scala-scala/src/library/scala/runtime/AbstractFunction7.scala
+../scala-scala/src/library/scala/runtime/AbstractFunction8.scala
+../scala-scala/src/library/scala/runtime/AbstractFunction9.scala
+../scala-scala/src/library/scala/runtime/AbstractPartialFunction.scala
+../scala-scala/src/library/scala/runtime/Boxed.scala
+../scala-scala/src/library/scala/runtime/MethodCache.scala
+../scala-scala/src/library/scala/runtime/NonLocalReturnControl.scala
+../scala-scala/src/library/scala/runtime/Nothing$.scala
+../scala-scala/src/library/scala/runtime/Null$.scala
+../scala-scala/src/library/scala/runtime/package.scala
+../scala-scala/src/library/scala/runtime/ScalaNumberProxy.scala
+../scala-scala/src/library/scala/runtime/ScalaRunTime.scala
+../scala-scala/src/library/scala/runtime/SeqCharSequence.scala
+../scala-scala/src/library/scala/runtime/StringAdd.scala
+../scala-scala/src/library/scala/runtime/StringFormat.scala
+
+../scala-scala/src/library/scala/App.scala
+
+../scala-scala/src/library/scala/Function.scala
+../scala-scala/src/library/scala/Function0.scala
+#../scala-scala/src/library/scala/Function1.scala
+#../scala-scala/src/library/scala/Function2.scala
+../scala-scala/src/library/scala/Function3.scala
+../scala-scala/src/library/scala/Function4.scala
+../scala-scala/src/library/scala/Function5.scala
+../scala-scala/src/library/scala/Function6.scala
+../scala-scala/src/library/scala/Function7.scala
+../scala-scala/src/library/scala/Function8.scala
+../scala-scala/src/library/scala/Function9.scala
+../scala-scala/src/library/scala/Function10.scala
+../scala-scala/src/library/scala/Function11.scala
+../scala-scala/src/library/scala/Function12.scala
+../scala-scala/src/library/scala/Function13.scala
+../scala-scala/src/library/scala/Function14.scala
+../scala-scala/src/library/scala/Function15.scala
+../scala-scala/src/library/scala/Function16.scala
+../scala-scala/src/library/scala/Function17.scala
+../scala-scala/src/library/scala/Function18.scala
+../scala-scala/src/library/scala/Function19.scala
+../scala-scala/src/library/scala/Function20.scala
+../scala-scala/src/library/scala/Function21.scala
+../scala-scala/src/library/scala/Function22.scala
+
+../scala-scala/src/library/scala/Tuple1.scala
+../scala-scala/src/library/scala/Tuple2.scala
+../scala-scala/src/library/scala/Tuple3.scala
+../scala-scala/src/library/scala/Tuple4.scala
+../scala-scala/src/library/scala/Tuple5.scala
+../scala-scala/src/library/scala/Tuple6.scala
+../scala-scala/src/library/scala/Tuple7.scala
+../scala-scala/src/library/scala/Tuple8.scala
+../scala-scala/src/library/scala/Tuple9.scala
+../scala-scala/src/library/scala/Tuple10.scala
+../scala-scala/src/library/scala/Tuple11.scala
+../scala-scala/src/library/scala/Tuple12.scala
+../scala-scala/src/library/scala/Tuple13.scala
+../scala-scala/src/library/scala/Tuple14.scala
+../scala-scala/src/library/scala/Tuple15.scala
+../scala-scala/src/library/scala/Tuple16.scala
+../scala-scala/src/library/scala/Tuple17.scala
+../scala-scala/src/library/scala/Tuple18.scala
+../scala-scala/src/library/scala/Tuple19.scala
+../scala-scala/src/library/scala/Tuple20.scala
+../scala-scala/src/library/scala/Tuple21.scala
+../scala-scala/src/library/scala/Tuple22.scala
diff --git a/compiler/test/dotc/tests.scala b/compiler/test/dotc/tests.scala
index b389c6ae9..a7961d937 100644
--- a/compiler/test/dotc/tests.scala
+++ b/compiler/test/dotc/tests.scala
@@ -3,6 +3,7 @@ package dotc
import dotty.Jars
import dotty.tools.dotc.CompilerTest
import org.junit.{Before, Test}
+import org.junit.Assert._
import java.io.{ File => JFile }
import scala.reflect.io.Directory
@@ -84,6 +85,7 @@ class tests extends CompilerTest {
val runDir = testsDir + "run/"
val newDir = testsDir + "new/"
val replDir = testsDir + "repl/"
+ val javaDir = testsDir + "pos-java-interop/"
val sourceDir = "./src/"
val dottyDir = sourceDir + "dotty/"
@@ -96,6 +98,9 @@ class tests extends CompilerTest {
val typerDir = dotcDir + "typer/"
val libDir = "../library/src/"
+ def dottyBootedLib = compileDir(libDir, ".", List("-deep", "-Ycheck-reentrant", "-strict") ::: defaultOptions)(allowDeepSubtypes) // note the -deep argument
+ def dottyDependsOnBootedLib = compileDir(dottyDir, ".", List("-deep", "-Ycheck-reentrant", "-strict") ::: defaultOptions)(allowDeepSubtypes) // note the -deep argument
+
@Before def cleanup(): Unit = {
// remove class files from stdlib and tests compilation
Directory(defaultOutputDir + "scala").deleteRecursively()
@@ -196,12 +201,49 @@ class tests extends CompilerTest {
@Test def run_all = runFiles(runDir)
- val stdlibFiles = Source.fromFile("./test/dotc/scala-collections.whitelist", "UTF8").getLines()
- .map(_.trim) // allow identation
- .filter(!_.startsWith("#")) // allow comment lines prefixed by #
- .map(_.takeWhile(_ != '#').trim) // allow comments in the end of line
- .filter(_.nonEmpty)
- .toList
+ def loadList(path: String) = Source.fromFile(path, "UTF8").getLines()
+ .map(_.trim) // allow identation
+ .filter(!_.startsWith("#")) // allow comment lines prefixed by #
+ .map(_.takeWhile(_ != '#').trim) // allow comments in the end of line
+ .filter(_.nonEmpty)
+ .toList
+
+ private def stdlibWhitelistFile = "./test/dotc/scala-collections.whitelist"
+ private def stdlibBlackFile = "./test/dotc/scala-collections.blacklist"
+
+ private val stdlibFiles: List[String] = loadList(stdlibWhitelistFile)
+
+ @Test def checkWBLists = {
+ val stdlibFilesBlackListed = loadList(stdlibBlackFile)
+
+ def checkForRepeated(list: List[String], listFile: String) = {
+ val duplicates = list.groupBy(x => x).filter(_._2.size > 1).filter(_._2.size > 1)
+ val msg = duplicates.map(x => s"'${x._1}' appears ${x._2.size} times").mkString(s"Duplicate entries in $listFile:\n", "\n", "\n")
+ assertTrue(msg, duplicates.isEmpty)
+ }
+ checkForRepeated(stdlibFiles, stdlibWhitelistFile)
+ checkForRepeated(stdlibFilesBlackListed, stdlibBlackFile)
+
+ val whitelistSet = stdlibFiles.toSet
+ val blacklistSet = stdlibFilesBlackListed.toSet
+
+ val intersection = whitelistSet.intersect(blacklistSet)
+ val msgIntersection =
+ intersection.map(x => s"'$x'").mkString(s"Entries where found in both $stdlibWhitelistFile and $stdlibBlackFile:\n", "\n", "\n")
+ assertTrue(msgIntersection, intersection.isEmpty)
+
+ def collectAllFilesInDir(dir: JFile, acc: List[String]): List[String] = {
+ val files = dir.listFiles()
+ val acc2 = files.foldLeft(acc)((acc1, file) => if (file.isFile && file.getPath.endsWith(".scala")) file.getPath :: acc1 else acc1)
+ files.foldLeft(acc2)((acc3, file) => if (file.isDirectory) collectAllFilesInDir(file, acc3) else acc3)
+ }
+ val filesInStdLib = collectAllFilesInDir(new JFile("../scala-scala/src/library/"), Nil)
+ val missingFiles = filesInStdLib.toSet -- whitelistSet -- blacklistSet
+ val msgMissing =
+ missingFiles.map(x => s"'$x'").mkString(s"Entries are missing in $stdlibWhitelistFile or $stdlibBlackFile:\n", "\n", "\n")
+ assertTrue(msgMissing, missingFiles.isEmpty)
+ }
+
@Test def compileStdLib = compileList("compileStdLib", stdlibFiles, "-migration" :: "-Yno-inline" :: scala2mode)
@Test def compileMixed = compileLine(
@@ -214,11 +256,10 @@ class tests extends CompilerTest {
|../scala-scala/src/library/scala/collection/generic/GenSeqFactory.scala""".stripMargin)
@Test def compileIndexedSeq = compileLine("../scala-scala/src/library/scala/collection/immutable/IndexedSeq.scala")
- // Not a junit test anymore since it is order dependent
- def dottyBootedLib = compileDir(libDir, ".")(allowDeepSubtypes) // note the -deep argument
-
- // Not a junit test anymore since it is order dependent
- def dottyDependsOnBootedLib = compileDir(dottyDir, ".")(allowDeepSubtypes) // note the -deep argument
+ @Test def dotty = {
+ dottyBootedLib
+ dottyDependsOnBootedLib
+ }
@Test def dotc_ast = compileDir(dotcDir, "ast")
@Test def dotc_config = compileDir(dotcDir, "config")
@@ -238,7 +279,7 @@ class tests extends CompilerTest {
@Test def dotc_typer = compileDir(dotcDir, "typer")// twice omitted to make tests run faster
// error: error while loading Checking$$anon$2$,
- // class file 'target/scala-2.11/dotty_2.11-0.1-SNAPSHOT.jar(dotty/tools/dotc/typer/Checking$$anon$2.class)'
+ // class file 'target/scala-2.11/dotty_2.11-0.1.1-SNAPSHOT.jar(dotty/tools/dotc/typer/Checking$$anon$2.class)'
// has location not matching its contents: contains class $anon
@Test def dotc_util = compileDir(dotcDir, "util") // twice omitted to make tests run faster
@@ -260,7 +301,6 @@ class tests extends CompilerTest {
dotcDir + "config/PathResolver.scala"
), List(/* "-Ylog:frontend", */ "-Xprompt") ++ staleSymbolError ++ twice)
- val javaDir = "./tests/pos-java-interop/"
@Test def java_all = compileFiles(javaDir, twice)
//@Test def dotc_compilercommand = compileFile(dotcDir + "config/", "CompilerCommand")
@@ -349,9 +389,10 @@ class tests extends CompilerTest {
@Test def tasty_tests = compileDir(testsDir, "tasty", testPickling)
@Test def tasty_bootstrap = {
- val opt = List("-priorityclasspath", defaultOutputDir, "-Ylog-classpath")
+ val logging = if (false) List("-Ylog-classpath", "-verbose") else Nil
+ val opt = List("-priorityclasspath", defaultOutputDir) ++ logging
// first compile dotty
- compileDir(dottyDir, ".", List("-deep", "-Ycheck-reentrant", "-strict"))(allowDeepSubtypes)
+ compileDir(dottyDir, ".", List("-deep", "-Ycheck-reentrant", "-strict") ++ logging)(allowDeepSubtypes)
compileDir(libDir, "dotty", "-deep" :: opt)
compileDir(libDir, "scala", "-deep" :: opt)
diff --git a/compiler/test/dotty/Jars.scala b/compiler/test/dotty/Jars.scala
index 42c707069..6fc9b0fde 100644
--- a/compiler/test/dotty/Jars.scala
+++ b/compiler/test/dotty/Jars.scala
@@ -3,15 +3,15 @@ package dotty
/** Jars used when compiling test, defaults to sbt locations */
object Jars {
val dottyLib: String = sys.env.get("DOTTY_LIB") getOrElse {
- "../library/target/scala-2.11/dotty-library_2.11-0.1-SNAPSHOT.jar"
+ "../library/target/scala-2.11/dotty-library_2.11-0.1.1-SNAPSHOT.jar"
}
val dottyCompiler: String = sys.env.get("DOTTY_COMPILER") getOrElse {
- "./target/scala-2.11/dotty-compiler_2.11-0.1-SNAPSHOT.jar"
+ "./target/scala-2.11/dotty-compiler_2.11-0.1.1-SNAPSHOT.jar"
}
val dottyInterfaces: String = sys.env.get("DOTTY_INTERFACE") getOrElse {
- "../interfaces/target/dotty-interfaces-0.1-SNAPSHOT.jar"
+ "../interfaces/target/dotty-interfaces-0.1.1-SNAPSHOT.jar"
}
val dottyExtras: List[String] = sys.env.get("DOTTY_EXTRAS")
diff --git a/compiler/test/dotty/tools/dotc/CompilerTest.scala b/compiler/test/dotty/tools/dotc/CompilerTest.scala
index 5192ec84c..eaa0bea84 100644
--- a/compiler/test/dotty/tools/dotc/CompilerTest.scala
+++ b/compiler/test/dotty/tools/dotc/CompilerTest.scala
@@ -228,8 +228,9 @@ abstract class CompilerTest {
} else {
val destDir = Directory(DPConfig.testRoot + JFile.separator + testName)
files.foreach({ file =>
- val jfile = new JFile(file)
- recCopyFiles(jfile, destDir / jfile.getName)
+ val sourceFile = new JFile(file)
+ val destFile = destDir / (if (file.startsWith("../")) file.substring(3) else file)
+ recCopyFiles(sourceFile, destFile)
})
compileDir(DPConfig.testRoot + JFile.separator, testName, args)
destDir.deleteRecursively
diff --git a/compiler/test/dotty/tools/dotc/parsing/ModifiersParsingTest.scala b/compiler/test/dotty/tools/dotc/parsing/ModifiersParsingTest.scala
index e31ef2160..32f842e92 100644
--- a/compiler/test/dotty/tools/dotc/parsing/ModifiersParsingTest.scala
+++ b/compiler/test/dotty/tools/dotc/parsing/ModifiersParsingTest.scala
@@ -140,12 +140,12 @@ class ModifiersParsingTest {
source = "def f(implicit a: Int, b: Int) = ???"
println(source.defParam(0).modifiers)
- assert(source.defParam(0).modifiers == List(Mod.Implicit(Flags.Implicit)))
- assert(source.defParam(1).modifiers == List(Mod.Implicit(Flags.Implicit)))
+ assert(source.defParam(0).modifiers == List(Mod.Implicit()))
+ assert(source.defParam(1).modifiers == List(Mod.Implicit()))
source = "def f(x: Int, y: Int)(implicit a: Int, b: Int) = ???"
assert(source.defParam(0, 0).modifiers == List())
- assert(source.defParam(1, 0).modifiers == List(Mod.Implicit(Flags.Implicit)))
+ assert(source.defParam(1, 0).modifiers == List(Mod.Implicit()))
}
@Test def blockDef = {
diff --git a/compiler/test/dotty/tools/dotc/transform/PatmatExhaustivityTest.scala b/compiler/test/dotty/tools/dotc/transform/PatmatExhaustivityTest.scala
index c77ba501f..d9a5d8a38 100644
--- a/compiler/test/dotty/tools/dotc/transform/PatmatExhaustivityTest.scala
+++ b/compiler/test/dotty/tools/dotc/transform/PatmatExhaustivityTest.scala
@@ -9,9 +9,9 @@ import dotty.tools.dotc.Main
import dotty.tools.dotc.reporting.TestReporter
class PatmatExhaustivityTest {
- val testsDir = "./tests/patmat"
+ val testsDir = "../tests/patmat"
// stop-after: patmatexhaust-huge.scala crash compiler
- val options = List("-color:never", "-Ystop-after:splitter", "-Ycheck-all-patmat")
+ val options = List("-color:never", "-Ystop-after:splitter", "-Ycheck-all-patmat") ++ (new dotc.tests).classPath
private def compileFile(file: File) = {
val stringBuffer = new StringWriter()
diff --git a/doc-tool/src/dotty/tools/dottydoc/core/DocASTPhase.scala b/doc-tool/src/dotty/tools/dottydoc/core/DocASTPhase.scala
index 806d9d0ae..483c22984 100644
--- a/doc-tool/src/dotty/tools/dottydoc/core/DocASTPhase.scala
+++ b/doc-tool/src/dotty/tools/dottydoc/core/DocASTPhase.scala
@@ -8,6 +8,7 @@ import dotc.CompilationUnit
import dotc.config.Printers.dottydoc
import dotc.core.Contexts.Context
import dotc.core.Comments.ContextDocstrings
+import dotc.core.Types.NoType
import dotc.core.Phases.Phase
import dotc.core.Symbols.{ Symbol, NoSymbol }
@@ -44,32 +45,35 @@ class DocASTPhase extends Phase {
}
def membersFromSymbol(sym: Symbol): List[Entity] = {
- val defs = sym.info.bounds.hi.membersBasedOnFlags(Flags.Method, Flags.Synthetic | Flags.Private)
- .filterNot(_.symbol.owner.name.show == "Any")
- .map { meth =>
- DefImpl(
- meth.symbol,
- meth.symbol.name.show,
- Nil,
- path(meth.symbol),
- returnType(meth.info),
- typeParams(meth.symbol),
- paramLists(meth.info),
- implicitlyAddedFrom = Some(returnType(meth.symbol.owner.info))
+ if (sym.info ne NoType) {
+ val defs = sym.info.bounds.hi.finalResultType.membersBasedOnFlags(Flags.Method, Flags.Synthetic | Flags.Private)
+ .filterNot(_.symbol.owner.name.show == "Any")
+ .map { meth =>
+ DefImpl(
+ meth.symbol,
+ meth.symbol.name.show,
+ Nil,
+ path(meth.symbol),
+ returnType(meth.info),
+ typeParams(meth.symbol),
+ paramLists(meth.info),
+ implicitlyAddedFrom = Some(returnType(meth.symbol.owner.info))
+ )
+ }.toList
+
+ val vals = sym.info.fields.filterNot(_.symbol.is(Flags.Private | Flags.Synthetic)).map { value =>
+ ValImpl(
+ value.symbol,
+ value.symbol.name.show,
+ Nil, path(value.symbol),
+ returnType(value.info),
+ implicitlyAddedFrom = Some(returnType(value.symbol.owner.info))
)
- }.toList
-
- val vals = sym.info.fields.filterNot(_.symbol.is(Flags.Private | Flags.Synthetic)).map { value =>
- ValImpl(
- value.symbol,
- value.symbol.name.show,
- Nil, path(value.symbol),
- returnType(value.info),
- implicitlyAddedFrom = Some(returnType(value.symbol.owner.info))
- )
- }
+ }
- defs ++ vals
+ defs ++ vals
+ }
+ else Nil
}
diff --git a/doc-tool/src/dotty/tools/dottydoc/model/factories.scala b/doc-tool/src/dotty/tools/dottydoc/model/factories.scala
index f95474ef1..433431f1c 100644
--- a/doc-tool/src/dotty/tools/dottydoc/model/factories.scala
+++ b/doc-tool/src/dotty/tools/dottydoc/model/factories.scala
@@ -9,6 +9,7 @@ import dotc.core.TypeApplications._
import dotc.core.Contexts.Context
import dotc.core.Symbols.{ Symbol, ClassSymbol }
import dotty.tools.dotc.core.SymDenotations._
+import dotty.tools.dotc.config.Printers.dottydoc
import dotty.tools.dotc.core.Names.TypeName
import dotc.ast.Trees._
@@ -105,6 +106,17 @@ object factories {
else paramName
typeRef(name)
+ case tr: TermRef =>
+ /** A `TermRef` appears in the return type in e.g:
+ * ```
+ * def id[T](t: T): t.type = t
+ * ```
+ */
+ val name = tr.show
+ if (!name.endsWith(".type"))
+ ctx.warning(s"unhandled return type found: $tr")
+
+ typeRef(name, params = params)
}
expandTpe(t)
@@ -154,7 +166,8 @@ object factories {
case annot: AnnotatedType => paramLists(annot.tpe)
case (_: PolyParam | _: RefinedType | _: TypeRef | _: ThisType |
- _: ExprType | _: OrType | _: AndType | _: HKApply) => Nil // return types should not be in the paramlist
+ _: ExprType | _: OrType | _: AndType | _: HKApply | _: TermRef) =>
+ Nil // return types should not be in the paramlist
}
def superTypes(t: Tree)(implicit ctx: Context): List[MaterializableLink] = t.symbol.denot match {
diff --git a/doc-tool/test/BaseTest.scala b/doc-tool/test/BaseTest.scala
index 7f3d62277..835911ca5 100644
--- a/doc-tool/test/BaseTest.scala
+++ b/doc-tool/test/BaseTest.scala
@@ -23,7 +23,7 @@ trait DottyTest {
ctx.setProperty(ContextDoc, new ContextDottydoc)
ctx.setSetting(
ctx.settings.classpath,
- "../library/target/scala-2.11/dotty-library_2.11-0.1-SNAPSHOT.jar"
+ "../library/target/scala-2.11/dotty-library_2.11-0.1.1-SNAPSHOT.jar"
)
base.initialize()(ctx)
ctx
diff --git a/docs/blog/_posts/2016-12-05-implicit-function-types.md b/docs/blog/_posts/2016-12-05-implicit-function-types.md
new file mode 100644
index 000000000..670c652ee
--- /dev/null
+++ b/docs/blog/_posts/2016-12-05-implicit-function-types.md
@@ -0,0 +1,364 @@
+---
+layout: blog
+title: Implicit Function Types
+author: Martin Odersky
+authorImg: /images/martin.jpg
+---
+
+I just made the [first pull request](https://github.com/lampepfl/dotty/pull/1775) to add _implicit function types_ to
+Scala. I am pretty excited about it, because - citing the explanation
+of the pull request - "_This is the first step to bring contextual
+abstraction to Scala_". What do I mean by this?
+
+**Abstraction**: The ability to name a concept and use just the name afterwards.
+
+**Contextual**: A piece of a program produces results or outputs in
+some context. Our programming languages are very good in describing
+and abstracting what outputs are produced. But there's hardly anything
+yet available to abstract over the inputs that programs get from their
+context. Many interesting scenarios fall into that category,
+including:
+
+ - passing configuration data to the parts of a system that need them,
+ - managing capabilities for security critical tasks,
+ - wiring components up with dependency injection,
+ - defining the meanings of operations with type classes,
+ - more generally, passing any sort of context to a computation.
+
+Implicit function types are a surprisingly simple and general way to
+make coding patterns solving these tasks abstractable, reducing
+boilerplate code and increasing applicability.
+
+**First Step**: My pull request is a first implementation. It solves the
+ problem in principle, but introduces some run-time overhead. The
+ next step will be to eliminate the run-time overhead through some
+ simple optimizations.
+
+## Implicit Parameters
+
+In a functional setting, the inputs to a computation are most
+naturally expressed as _parameters_. One could simply augment
+functions to take additional parameters that represent configurations,
+capabilities, dictionaries, or whatever contextual data the functions
+need. The only downside with this is that often there's a large
+distance in the call graph between the definition of a contextual
+element and the site where it is used. Consequently, it becomes
+tedious to define all those intermediate parameters and to pass them
+along to where they are eventually consumed.
+
+Implicit parameters solve one half of the problem. Implicit
+parameters do not have to be propagated using boilerplate code; the
+compiler takes care of that. This makes them practical in many
+scenarios where plain parameters would be too cumbersome. For
+instance, type classes would be a lot less popular if one would have
+to pass all dictionaries by hand. Implicit parameters are also very
+useful as a general context passing mechanism. For instance in the
+_dotty_ compiler, almost every function takes an implicit context
+parameter which defines all elements relating to the current state of
+the compilation. This is in my experience much better than the cake
+pattern because it is lightweight and can express context changes in a
+purely functional way.
+
+The main downside of implicit parameters is the verbosity of their
+declaration syntax. It's hard to illustrate this with a smallish example,
+because it really only becomes a problem at scale, but let's try anyway.
+
+Let's say we want to write some piece of code that's designed to run
+in a transaction. For the sake of illustration here's a simple transaction class:
+
+ class Transaction {
+ private val log = new ListBuffer[String]
+ def println(s: String): Unit = log += s
+
+ private var aborted = false
+ private var committed = false
+
+ def abort(): Unit = { aborted = true }
+ def isAborted = aborted
+
+ def commit(): Unit =
+ if (!aborted && !committed) {
+ Console.println("******* log ********")
+ log.foreach(Console.println)
+ committed = true
+ }
+ }
+
+The transaction encapsulates a log, to which one can print messages.
+It can be in one of three states: running, committed, or aborted.
+If the transaction is committed, it prints the stored log to the console.
+
+The `transaction` method lets one run some given code `op` inside
+a newly created transaction:
+
+ def transaction[T](op: Transaction => T) = {
+ val trans: Transaction = new Transaction
+ op(trans)
+ trans.commit()
+ }
+
+The current transaction needs to be passed along a call chain to all
+the places that need to access it. To illustrate this, here are three
+functions `f1`, `f2` and `f3` which call each other, and also access
+the current transaction. The most convenient way to achieve this is
+by passing the current transaction as an implicit parameter.
+
+ def f1(x: Int)(implicit thisTransaction: Transaction): Int = {
+ thisTransaction.println(s"first step: $x")
+ f2(x + 1)
+ }
+ def f2(x: Int)(implicit thisTransaction: Transaction): Int = {
+ thisTransaction.println(s"second step: $x")
+ f3(x * x)
+ }
+ def f3(x: Int)(implicit thisTransaction: Transaction): Int = {
+ thisTransaction.println(s"third step: $x")
+ if (x % 2 != 0) thisTransaction.abort()
+ x
+ }
+
+The main program calls `f1` in a fresh transaction context and prints
+its result:
+
+ def main(args: Array[String]) = {
+ transaction {
+ implicit thisTransaction =>
+ val res = f1(args.length)
+ println(if (thisTransaction.isAborted) "aborted" else s"result: $res")
+ }
+ }
+
+Two sample calls of the program (let's call it `TransactionDemo`) are here:
+
+ scala TransactionDemo 1 2 3
+ result: 16
+ ******* log ********
+ first step: 3
+ second step: 4
+ third step: 16
+
+ scala TransactionDemo 1 2 3 4
+ aborted
+
+So far, so good. The code above is quite compact as far as expressions
+are concerned. In particular, it's nice that, being implicit
+parameters, none of the transaction values had to be passed along
+explicitly in a call. But on the definition side, things are less
+rosy: Every one of the functions `f1` to `f3` needed an additional
+implicit parameter:
+
+ (implicit thisTransaction: Transaction)
+
+A three-times repetition might not look so bad here, but it certainly
+smells of boilerplate. In real-sized projects, this can get much worse.
+For instance, the _dotty_ compiler uses implicit abstraction
+over contexts for most of its parts. Consequently it ends up with currently
+no fewer than 2641 occurrences of the text string
+
+ (implicit ctx: Context)
+
+It would be nice if we could get rid of them.
+
+## Implicit Functions
+
+Let's massage the definition of `f1` a bit by moving the last parameter section to the right of the equals sign:
+
+ def f1(x: Int) = { implicit thisTransaction: Transaction =>
+ thisTransaction.println(s"first step: $x")
+ f2(x + 1)
+ }
+
+The right hand side of this new version of `f1` is now an implicit
+function value. What's the type of this value? Previously, it was
+`Transaction => Int`, that is, the knowledge that the function has an
+implicit parameter got lost in the type. The main extension implemented by
+the pull request is to introduce implicit function types that mirror
+the implicit function values which we have already. Concretely, the new
+type of `f1` is:
+
+ implicit Transaction => Int
+
+Just like the normal function type syntax `A => B`, desugars to `scala.Function1[A, B]`
+the implicit function type syntax `implicit A => B` desugars to `scala.ImplicitFunction1[A, B]`.
+The same holds at other function arities. With dotty's [pull request #1758](https://github.com/lampepfl/dotty/pull/1758)
+merged there is no longer an upper limit of 22 for such functions.
+
+The type `ImplicitFunction1` can be thought of being defined as follows:
+
+ trait ImplicitFunction1[-T0, R] extends Function1[T0, R] {
+ override def apply(implicit x: T0): R
+ }
+
+However, you won't find a classfile for this trait because all implicit function traits
+get mapped to normal functions during type erasure.
+
+There are two rules that guide type checking of implicit function types.
+The first rule says that an implicit function is applied to implicit arguments
+in the same way an implicit method is. More precisely, if `t` is an expression
+of an implicit function type
+
+ t: implicit (T1, ..., Tn) => R
+
+such that `t` is not an implicit closure itself and `t` is not the
+prefix of a call `t.apply(...)`, then an `apply` is implicitly
+inserted, so `t` becomes `t.apply`. We have already seen that the
+definition of `t.apply` is an implicit method as given in the
+corresponding implicit function trait. Hence, it will in turn be
+applied to a matching sequence of implicit arguments. The end effect is
+that references to implicit functions get applied to implicit arguments in the
+same way as references to implicit methods.
+
+The second rule is the dual of the first. If the expected type
+of an expression `t` is an implicit function type
+
+ implicit (T1, ..., Tn) => R
+
+then `t` is converted to an implicit closure, unless it is already one.
+More precisely, `t` is mapped to the implicit closure
+
+ implicit ($ev1: T1, ..., $evn: Tn) => t
+
+The parameter names of this closure are compiler-generated identifiers
+which should not be accessed from user code. That is, the only way to
+refer to an implicit parameter of a compiler-generated function is via
+`implicitly`.
+
+It is important to note that this second conversion needs to be applied
+_before_ the expression `t` is typechecked. This is because the
+conversion establishes the necessary context to make type checking `t`
+succeed by defining the required implicit parameters.
+
+There is one final tweak to make this all work: When using implicit parameters
+for nested functions it was so far important to give all implicit parameters
+of the same type the same name, or else one would get ambiguities. For instance, consider the
+following fragment:
+
+ def f(implicit c: C) = {
+ def g(implicit c: C) = ... implicitly[C] ...
+ ...
+ }
+
+If we had named the inner parameter `d` instead of `c` we would
+have gotten an implicit ambiguity at the call of `implicitly` because
+both `c` and `d` would be eligible:
+
+ def f(implicit c: C) = {
+ def g(implicit d: C) = ... implicitly[C] ... // error!
+ ...
+ }
+
+The problem is that parameters in implicit closures now have
+compiler-generated names, so the programmer cannot enforce the proper
+naming scheme to avoid all ambiguities. We fix the problem by
+introducing a new disambiguation rule which makes nested occurrences
+of an implicit take precedence over outer ones. This rule, which
+applies to all implicit parameters and implicit locals, is conceptually
+analogous to the rule that prefers implicits defined in companion
+objects of subclasses over those defined in companion objects of
+superclass. With that new disambiguation rule the example code above
+now compiles.
+
+That's the complete set of rules needed to deal with implicit function types.
+
+## How to Remove Boilerplate
+
+The main advantage of implicit function types is that, being types,
+they can be abstracted. That is, one can define a name for an implicit
+function type and then use just the name instead of the full type.
+Let's revisit our previous example and see how it can be made more
+concise using this technique.
+
+We first define a type `Transactional` for functions that take an implicit parameter of type `Transaction`:
+
+ type Transactional[T] = implicit Transaction => T
+
+Making the return type of `f1` to `f3` a `Transactional[Int]`, we can
+eliminate their implicit parameter sections:
+
+ def f1(x: Int): Transactional[Int] = {
+ thisTransaction.println(s"first step: $x")
+ f2(x + 1)
+ }
+ def f2(x: Int): Transactional[Int] = {
+ thisTransaction.println(s"second step: $x")
+ f3(x * x)
+ }
+ def f3(x: Int): Transactional[Int] = {
+ thisTransaction.println(s"third step: $x")
+ if (x % 2 != 0) thisTransaction.abort()
+ x
+ }
+
+You might ask, how does `thisTransaction` typecheck, since there is no
+longer a parameter with that name? In fact, `thisTransaction` is now a
+global definition:
+
+ def thisTransaction: Transactional[Transaction] = implicitly[Transaction]
+
+You might ask: a `Transactional[Transaction]`, is that not circular? To see more clearly, let's expand
+the definition according to the rules given in the last section. `thisTransaction`
+is of implicit function type, so the right hand side is expanded to the
+implicit closure
+
+ implicit ($ev0: Transaction) => implicitly[Transaction]
+
+The right hand side of this closure, `implicitly[Transaction]`, needs
+an implicit parameter of type `Transaction`, so the closure is further
+expanded to
+
+ implicit ($ev0: Transaction) => implicitly[Transaction]($ev0)
+
+Now, `implicitly` is defined in `scala.Predef` like this:
+
+ def implicitly[T](implicit x: T) = x
+
+If we plug that definition into the closure above and simplify, we get:
+
+ implicit ($ev0: Transaction) => $ev0
+
+So, `thisTransaction` is just the implicit identity function on `transaction`!
+In other words, if we use `thisTransaction` in the body of `f1` to `f3`, it will
+pick up and return the unnamed implicit parameter that's in scope.
+
+Finally, here are the `transaction` and `main` method that complete
+the example. Since `transactional`'s parameter `op` is now a
+`Transactional`, we can eliminate the `Transaction` argument to `op`
+and the `Transaction` lambda in `main`; both will be added by the compiler.
+
+ def transaction[T](op: Transactional[T]) = {
+ implicit val trans: Transaction = new Transaction
+ op
+ trans.commit()
+ }
+ def main(args: Array[String]) = {
+ transaction {
+ val res = f1(args.length)
+ println(if (thisTransaction.isAborted) "aborted" else s"result: $res")
+ }
+ }
+
+## Categorically Speaking
+
+There are many interesting connections with category theory to explore
+here. On the one hand, implicit functions are used for tasks that are
+sometimes covered with monads such as the reader monad. There's an
+argument to be made that implicits have better composability than
+monads and why that is.
+
+On the other hand, it turns out that implicit functions can also be
+given a co-monadic interpretation, and the interplay between monads and
+comonads is very interesting in its own right.
+
+But these discussions will have to wait for another time, as
+this blog post is already too long.
+
+## Conclusion
+
+Implicit function types are unique way to abstract over the context in
+which some piece of code is run. I believe they will deeply influence
+the way we write Scala in the future. They are very powerful
+abstractions, in the sense that just declaring a type of a function
+will inject certain implicit values into the scope of the function's
+implementation. Can this be abused, making code more obscure?
+Absolutely, like every other powerful abstraction technique. To keep
+your code sane, please keep the [Principle of Least Power](http://www.lihaoyi.com/post/StrategicScalaStylePrincipleofLeastPower.html) in mind.
diff --git a/docs/docs/contributing/workflow.md b/docs/docs/contributing/workflow.md
index 48f71053e..fb8da0da3 100644
--- a/docs/docs/contributing/workflow.md
+++ b/docs/docs/contributing/workflow.md
@@ -33,7 +33,7 @@ Here are some useful debugging `<OPTIONS>`:
* `-Xprint:PHASE1,PHASE2,...` or `-Xprint:all`: prints the `AST` after each
specified phase. Phase names can be found by searching
- `src/dotty/tools/dotc/transform/` for `phaseName`.
+ `compiler/src/dotty/tools/dotc/transform/` for `phaseName`.
* `-Ylog:PHASE1,PHASE2,...` or `-Ylog:all`: enables `ctx.log("")` logging for
the specified phase.
* `-Ycheck:all` verifies the consistency of `AST` nodes between phases, in
@@ -42,7 +42,7 @@ Here are some useful debugging `<OPTIONS>`:
`-Ycheck:tailrec,resolveSuper,mixin,restoreScopes,labelDef`.
Additional logging information can be obtained by changes some `noPrinter` to
-`new Printer` in `src/dotty/tools/dotc/config/Printers.scala`. This enables the
+`new Printer` in `compiler/src/dotty/tools/dotc/config/Printers.scala`. This enables the
`subtyping.println("")` and `ctx.traceIndented("", subtyping)` style logging.
## Running tests ##
diff --git a/docs/docs/index.md b/docs/docs/index.md
index 8fceedbd0..0d9bc6b6f 100644
--- a/docs/docs/index.md
+++ b/docs/docs/index.md
@@ -20,6 +20,7 @@ Index
- [Eclipse](contributing/eclipse.md) setting up dev environment
- [Intellij-IDEA](contributing/intellij-idea.md) setting up dev environment
* Internals document the compiler internals
+ - [Syntax Summary](internals/syntax.md)
- [Project Structure](internals/overall-structure.md)
of the project
- [Backend](internals/backend.md) details on the bytecode backend
diff --git a/docs/docs/internals/backend.md b/docs/docs/internals/backend.md
index f10cf1e82..47974b5ff 100644
--- a/docs/docs/internals/backend.md
+++ b/docs/docs/internals/backend.md
@@ -4,7 +4,7 @@ title: "Backend Internals"
---
The code for the backend is split up by functionality and assembled in the
-objet `GenBCode`.
+object `GenBCode`.
```none
object GenBCode --- [defines] --> PlainClassBuilder GenBCode also defines class BCodePhase, the compiler phase
@@ -61,29 +61,29 @@ ready for serialization to disk.
Currently the queue subsystem is all sequential, but as can be seen in
http://magarciaepfl.github.io/scala/ the above design enables overlapping (a.1)
-building of ClassNodes, (a.2) intra-method optimizations, and (a.3)
+building of `ClassNodes`, (a.2) intra-method optimizations, and (a.3)
serialization to disk.
-This subsystem is described in detail in GenBCode.scala
+This subsystem is described in detail in `GenBCode.scala`
#### (b) Bytecode-level types, BType ####
The previous bytecode emitter goes to great lengths to reason about
bytecode-level types in terms of Symbols.
-GenBCode uses BType as a more direct representation. A BType is immutable, and
+`GenBCode` uses `BType` as a more direct representation. A `BType` is immutable, and
a value class (once the rest of GenBCode is merged from
http://magarciaepfl.github.io/scala/ ).
Whether value class or not, its API is the same. That API doesn't reach into
-the type checker. Instead, each method on a BType answers a question that can
-be answered based on the BType itself. Sounds too simple to be good? It's a
+the type checker. Instead, each method on a `BType` answers a question that can
+be answered based on the `BType` itself. Sounds too simple to be good? It's a
good building block, that's what it is.
-The internal representation of a BType is based on what the JVM uses: internal
-names (eg Ljava/lang/String; ) and method descriptors; as defined in the JVM
-spec (that's why they aren't documented in GenBCode, just read the spec).
+The internal representation of a `BType` is based on what the JVM uses: internal
+names (e.g. `Ljava/lang/String;` ) and method descriptors; as defined in the JVM
+spec (that's why they aren't documented in `GenBCode`, just read the [JVM 8 spec](https://docs.oracle.com/javase/specs/jvms/se8/html/)).
-All things BType can be found in BCodeGlue.scala
+All things `BType` can be found in `BCodeGlue.scala`
#### (c) Utilities offering a more "high-level" API to bytecode emission ####
Bytecode can be emitted one opcode at a time, but there are recurring patterns
@@ -93,7 +93,7 @@ For example, when emitting a load-constant, a dedicated instruction exists for
emitting load-zero. Similarly, emitting a switch can be done according to one
of two strategies.
-All these utilities are encapsulated in file BCodeIdiomatic.scala. They know
+All these utilities are encapsulated in file `BCodeIdiomatic.scala`. They know
nothing about the type checker (because, just between us, they don't need to).
#### (d) Mapping between type-checker types and BTypes ####
@@ -109,10 +109,10 @@ To understand how it's built, see:
final def exemplar(csym0: Symbol): Tracked = { ... }
```
-Details in BCodeTypes.scala
+Details in `BCodeTypes.scala`
#### (e) More "high-level" utilities for bytecode emission ####
-In the spirit of BCodeIdiomatic, utilities are added in BCodeHelpers for
+In the spirit of `BCodeIdiomatic`, utilities are added in `BCodeHelpers` for
emitting:
- bean info class
@@ -122,4 +122,4 @@ emitting:
#### (f) Building an ASM ClassNode given an AST TypeDef ####
-It's done by PlainClassBuilder
+It's done by `PlainClassBuilder`(see `GenBCode.scala`).
diff --git a/docs/docs/internals/overall-structure.md b/docs/docs/internals/overall-structure.md
index 08d9ebe97..1b4e22f1b 100644
--- a/docs/docs/internals/overall-structure.md
+++ b/docs/docs/internals/overall-structure.md
@@ -37,7 +37,7 @@ list of sub-packages and their focus.
├── reporting // Reporting of error messages, warnings and other info.
├── rewrite // Helpers for rewriting Scala 2's constructs into dotty's.
├── transform // Miniphases and helpers for tree transformations.
-├── typer //Type-checking and other frontend phases
+├── typer // Type-checking and other frontend phases
└── util // General purpose utility classes and modules.
```
@@ -93,7 +93,9 @@ phases. The current list of phases is specified in class [Compiler] as follows:
```scala
def phases: List[List[Phase]] = List(
List(new FrontEnd), // Compiler frontend: scanner, parser, namer, typer
+ List(new sbt.ExtractDependencies), // Sends information on classes' dependencies to sbt via callbacks
List(new PostTyper), // Additional checks and cleanups after type checking
+ List(new sbt.ExtractAPI), // Sends a representation of the API of classes to sbt via callbacks
List(new Pickler), // Generate TASTY info
List(new FirstTransform, // Some transformations to put trees into a canonical form
new CheckReentrant), // Internal use only: Check that compiled program has no data races involving global vars
@@ -106,18 +108,22 @@ phases. The current list of phases is specified in class [Compiler] as follows:
new TailRec, // Rewrite tail recursion to loops
new LiftTry, // Put try expressions that might execute on non-empty stacks into their own methods
new ClassOf), // Expand `Predef.classOf` calls.
- List(new PatternMatcher, // Compile pattern matches
+ List(new TryCatchPatterns, // Compile cases in try/catch
+ new PatternMatcher, // Compile pattern matches
new ExplicitOuter, // Add accessors to outer classes from nested ones.
new ExplicitSelf, // Make references to non-trivial self types explicit as casts
+ new ShortcutImplicits, // Allow implicit functions without creating closures
new CrossCastAnd, // Normalize selections involving intersection types.
new Splitter), // Expand selections involving union types into conditionals
List(new VCInlineMethods, // Inlines calls to value class methods
+ new IsInstanceOfEvaluator, // Issues warnings when unreachable statements are present in match/if expressions
new SeqLiterals, // Express vararg arguments as arrays
new InterceptedMethods, // Special handling of `==`, `|=`, `getClass` methods
new Getters, // Replace non-private vals and vars with getter defs (fields are added later)
new ElimByName, // Expand by-name parameters and arguments
new AugmentScala2Traits, // Expand traits defined in Scala 2.11 to simulate old-style rewritings
- new ResolveSuper), // Implement super accessors and add forwarders to trait methods
+ new ResolveSuper, // Implement super accessors and add forwarders to trait methods
+ new ArrayConstructors), // Intercept creation of (non-generic) arrays and intrinsify.
List(new Erasure), // Rewrite types to JVM model, erasing all type parameters, abstract types and refinements.
List(new ElimErasedValueType, // Expand erased value types to their underlying implementation types
new VCElideAllocations, // Peep-hole optimization to eliminate unnecessary value class allocations
@@ -137,9 +143,12 @@ phases. The current list of phases is specified in class [Compiler] as follows:
new Flatten, // Lift all inner classes to package scope
new RestoreScopes), // Repair scopes rendered invalid by moving definitions in prior phases of the group
List(new ExpandPrivate, // Widen private definitions accessed from nested classes
+ new SelectStatic, // get rid of selects that would be compiled into GetStatic
new CollectEntryPoints, // Find classes with main methods
+ new CollectSuperCalls, // Find classes that are called with super
+ new DropInlined, // Drop Inlined nodes, since backend has no use for them
+ new MoveStatics, // Move static methods to companion classes
new LabelDefs), // Converts calls to labels to jumps
- List(new GenSJSIR), // Generate .js code
List(new GenBCode) // Generate JVM bytecode
)
```
@@ -180,10 +189,10 @@ Phases fall into four categories:
* Code generators: These map the transformed trees to Java classfiles or
Javascript files.
-[dotty.tools]: https://github.com/lampepfl/dotty/tree/master/src/dotty/tools
-[dotc]: https://github.com/lampepfl/dotty/tree/master/src/dotty/tools/dotc
-[Main]: https://github.com/lampepfl/dotty/blob/master/src/dotty/tools/dotc/Main.scala
-[Driver]: https://github.com/lampepfl/dotty/blob/master/src/dotty/tools/dotc/Driver.scala
-[Compiler]: https://github.com/lampepfl/dotty/blob/master/src/dotty/tools/dotc/Compiler.scala
-[Run]: https://github.com/lampepfl/dotty/blob/master/src/dotty/tools/dotc/Run.scala
-[Context]: https://github.com/lampepfl/dotty/blob/master/src/dotty/tools/dotc/core/Contexts.scala
+[dotty.tools]: https://github.com/lampepfl/dotty/tree/master/compiler/src/dotty/tools
+[dotc]: https://github.com/lampepfl/dotty/tree/master/compiler/src/dotty/tools/dotc
+[Main]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/Main.scala
+[Driver]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/Driver.scala
+[Compiler]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/Compiler.scala
+[Run]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/Run.scala
+[Context]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/core/Contexts.scala
diff --git a/docs/docs/internals/syntax.md b/docs/docs/internals/syntax.md
new file mode 100644
index 000000000..7c8cb1ea2
--- /dev/null
+++ b/docs/docs/internals/syntax.md
@@ -0,0 +1,356 @@
+---
+layout: default
+title: "Scala Syntax Summary"
+---
+
+The following descriptions of Scala tokens uses literal characters `‘c’` when
+referring to the ASCII fragment `\u0000` – `\u007F`.
+
+_Unicode escapes_ are used to represent the Unicode character with the given
+hexadecimal code:
+
+```ebnf
+UnicodeEscape ::= ‘\’ ‘u’ {‘u’} hexDigit hexDigit hexDigit hexDigit
+hexDigit ::= ‘0’ | … | ‘9’ | ‘A’ | … | ‘F’ | ‘a’ | … | ‘f’
+```
+
+Informal descriptions are typeset as `“some comment”`.
+
+### Lexical Syntax
+The lexical syntax of Scala is given by the following grammar in EBNF
+form.
+
+```ebnf
+whiteSpace ::= ‘\u0020’ | ‘\u0009’ | ‘\u000D’ | ‘\u000A’
+upper ::= ‘A’ | … | ‘Z’ | ‘\$’ | ‘_’ “… and Unicode category Lu”
+lower ::= ‘a’ | … | ‘z’ “… and Unicode category Ll”
+letter ::= upper | lower “… and Unicode categories Lo, Lt, Nl”
+digit ::= ‘0’ | … | ‘9’
+paren ::= ‘(’ | ‘)’ | ‘[’ | ‘]’ | ‘{’ | ‘}’
+delim ::= ‘`’ | ‘'’ | ‘"’ | ‘.’ | ‘;’ | ‘,’
+opchar ::= “printableChar not matched by (whiteSpace | upper | lower |
+ letter | digit | paren | delim | opchar | Unicode_Sm |
+ Unicode_So)”
+printableChar ::= “all characters in [\u0020, \u007F] inclusive”
+charEscapeSeq ::= ‘\’ (‘b’ | ‘t’ | ‘n’ | ‘f’ | ‘r’ | ‘"’ | ‘'’ | ‘\’)
+
+op ::= opchar {opchar}
+varid ::= lower idrest
+alphaid ::= upper idrest
+ | varid
+plainid ::= alphaid
+ | op
+id ::= plainid
+ | ‘`’ { charNoBackQuoteOrNewline | UnicodeEscape | charEscapeSeq } ‘`’
+ | INT // interpolation id, only for quasi-quotes
+idrest ::= {letter | digit} [‘_’ op]
+
+integerLiteral ::= (decimalNumeral | hexNumeral) [‘L’ | ‘l’]
+decimalNumeral ::= ‘0’ | nonZeroDigit {digit}
+hexNumeral ::= ‘0’ (‘x’ | ‘X’) hexDigit {hexDigit}
+digit ::= ‘0’ | nonZeroDigit
+nonZeroDigit ::= ‘1’ | … | ‘9’
+
+floatingPointLiteral
+ ::= digit {digit} ‘.’ {digit} [exponentPart] [floatType]
+ | ‘.’ digit {digit} [exponentPart] [floatType]
+ | digit {digit} exponentPart [floatType]
+ | digit {digit} [exponentPart] floatType
+exponentPart ::= (‘E’ | ‘e’) [‘+’ | ‘-’] digit {digit}
+floatType ::= ‘F’ | ‘f’ | ‘D’ | ‘d’
+
+booleanLiteral ::= ‘true’ | ‘false’
+
+characterLiteral ::= ‘'’ (printableChar | charEscapeSeq) ‘'’
+
+stringLiteral ::= ‘"’ {stringElement} ‘"’
+ | ‘"""’ multiLineChars ‘"""’
+stringElement ::= printableChar \ (‘"’ | ‘\’)
+ | UnicodeEscape
+ | charEscapeSeq
+multiLineChars ::= {[‘"’] [‘"’] char \ ‘"’} {‘"’}
+processedStringLiteral
+ ::= alphaid ‘"’ {printableChar \ (‘"’ | ‘$’) | escape} ‘"’
+ | alphaid ‘"""’ {[‘"’] [‘"’] char \ (‘"’ | ‘$’) | escape} {‘"’} ‘"""’
+escape ::= ‘$$’
+ | ‘$’ letter { letter | digit }
+ | ‘{’ Block [‘;’ whiteSpace stringFormat whiteSpace] ‘}’
+stringFormat ::= {printableChar \ (‘"’ | ‘}’ | ‘ ’ | ‘\t’ | ‘\n’)}
+
+symbolLiteral ::= ‘'’ plainid
+
+comment ::= ‘/*’ “any sequence of characters; nested comments are allowed” ‘*/’
+ | ‘//’ “any sequence of characters up to end of line”
+
+nl ::= “new line character”
+semi ::= ‘;’ | nl {nl}
+```
+
+
+## Context-free Syntax
+
+The context-free syntax of Scala is given by the following EBNF
+grammar:
+
+### Literals and Paths
+```ebnf
+SimpleLiteral ::= [‘-’] integerLiteral
+ | [‘-’] floatingPointLiteral
+ | booleanLiteral
+ | characterLiteral
+ | stringLiteral
+Literal ::= SimpleLiteral
+ | processedStringLiteral
+ | symbolLiteral
+ | ‘null’
+
+QualId ::= id {‘.’ id}
+ids ::= id {‘,’ id}
+
+Path ::= StableId
+ | [id ‘.’] ‘this’
+StableId ::= id
+ | Path ‘.’ id
+ | [id ‘.’] ‘super’ [ClassQualifier] ‘.’ id
+ClassQualifier ::= ‘[’ id ‘]’
+```
+
+### Types
+```ebnf
+Type ::= [‘implicit’] FunArgTypes ‘=>’ Type Function(ts, t)
+ | HkTypeParamClause ‘=>’ Type TypeLambda(ps, t)
+ | InfixType
+FunArgTypes ::= InfixType
+ | ‘(’ [ FunArgType {‘,’ FunArgType } ] ‘)’
+InfixType ::= RefinedType {id [nl] RefinedType} InfixOp(t1, op, t2)
+RefinedType ::= WithType {[nl] Refinement} RefinedTypeTree(t, ds)
+WithType ::= AnnotType {‘with’ AnnotType} (deprecated)
+AnnotType ::= SimpleType {Annotation} Annotated(t, annot)
+SimpleType ::= SimpleType (TypeArgs | NamedTypeArgs) AppliedTypeTree(t, args)
+ | SimpleType ‘#’ id Select(t, name)
+ | StableId
+ | Path ‘.’ ‘type’ SingletonTypeTree(p)
+ | ‘(’ ArgTypes ‘)’ Tuple(ts)
+ | ‘_’ TypeBounds
+ | Refinement RefinedTypeTree(EmptyTree, refinement)
+ | SimpleLiteral SingletonTypeTree(l)
+ArgTypes ::= Type {‘,’ Type}
+ | NamedTypeArg {‘,’ NamedTypeArg}
+FunArgType ::= Type
+ | ‘=>’ Type PrefixOp(=>, t)
+ParamType ::= [‘=>’] ParamValueType
+ParamValueType ::= Type [‘*’] PostfixOp(t, "*")
+TypeArgs ::= ‘[’ ArgTypes ‘]’ ts
+NamedTypeArg ::= id ‘=’ Type NamedArg(id, t)
+NamedTypeArgs ::= ‘[’ NamedTypeArg {‘,’ NamedTypeArg} ‘]’ nts
+Refinement ::= ‘{’ [Dcl] {semi [Dcl]} ‘}’ ds
+TypeBounds ::= [‘>:’ Type] [‘<:’ Type] | INT TypeBoundsTree(lo, hi)
+TypeParamBounds ::= TypeBounds {‘<%’ Type} {‘:’ Type} ContextBounds(typeBounds, tps)
+```
+
+### Expressions
+```ebnf
+Expr ::= [‘implicit’] FunParams ‘=>’ Expr Function(args, expr), Function(ValDef([implicit], id, TypeTree(), EmptyTree), expr)
+ | Expr1
+BlockResult ::= [‘implicit’] FunParams ‘=>’ Block
+ | Expr1
+FunParams ::= Bindings
+ | id
+ | ‘_’
+Expr1 ::= ‘if’ ‘(’ Expr ‘)’ {nl} Expr [[semi] ‘else’ Expr] If(Parens(cond), thenp, elsep?)
+ | ‘if’ Expr ‘then’ Expr [[semi] ‘else’ Expr] If(cond, thenp, elsep?)
+ | ‘while’ ‘(’ Expr ‘)’ {nl} Expr WhileDo(Parens(cond), body)
+ | ‘while’ Expr ‘do’ Expr WhileDo(cond, body)
+ | ‘do’ Expr [semi] ‘while’ Expr DoWhile(expr, cond)
+ | ‘try’ Expr Catches [‘finally’ Expr] Try(expr, catches, expr?)
+ | ‘try’ Expr [‘finally’ Expr] Try(expr, Nil, expr?)
+ | ‘throw’ Expr Throw(expr)
+ | ‘return’ [Expr] Return(expr?)
+ | ForExpr
+ | [SimpleExpr ‘.’] id ‘=’ Expr Assign(expr, expr)
+ | SimpleExpr1 ArgumentExprs ‘=’ Expr Assign(expr, expr)
+ | PostfixExpr [Ascription]
+ | PostfixExpr ‘match’ ‘{’ CaseClauses ‘}’ Match(expr, cases) -- point on match
+Ascription ::= ‘:’ InfixType Typed(expr, tp)
+ | ‘:’ Annotation {Annotation} Typed(expr, Annotated(EmptyTree, annot)*)
+Catches ::= ‘catch’ Expr
+PostfixExpr ::= InfixExpr [id] PostfixOp(expr, op)
+InfixExpr ::= PrefixExpr
+ | InfixExpr id [nl] InfixExpr InfixOp(expr, op, expr)
+PrefixExpr ::= [‘-’ | ‘+’ | ‘~’ | ‘!’] SimpleExpr PrefixOp(expr, op)
+SimpleExpr ::= ‘new’ Template New(templ)
+ | BlockExpr
+ | SimpleExpr1 [‘_’] PostfixOp(expr, _)
+SimpleExpr1 ::= Literal
+ | Path
+ | ‘_’
+ | ‘(’ ExprsInParens ‘)’ Parens(exprs)
+ | SimpleExpr ‘.’ id Select(expr, id)
+ | SimpleExpr (TypeArgs | NamedTypeArgs) TypeApply(expr, args)
+ | SimpleExpr1 ArgumentExprs Apply(expr, args)
+ | XmlExpr
+ExprsInParens ::= ExprInParens {‘,’ ExprInParens}
+ExprInParens ::= PostfixExpr ‘:’ Type
+ | Expr
+ParArgumentExprs ::= ‘(’ ExprsInParens ‘)’ exprs
+ | ‘(’ [ExprsInParens] PostfixExpr ‘:’ ‘_’ ‘*’ ‘)’ exprs :+ Typed(expr, Ident(wildcardStar))
+ArgumentExprs ::= ParArgumentExprs
+ | [nl] BlockExpr
+BlockExpr ::= ‘{’ CaseClauses ‘}’ Match(EmptyTree, cases)
+ | ‘{’ Block ‘}’ block // starts at {
+Block ::= {BlockStat semi} [BlockResult] Block(stats, expr?)
+BlockStat ::= Import
+ | {Annotation} [‘implicit’ | ‘lazy’] Def
+ | {Annotation} {LocalModifier} TmplDef
+ | Expr1
+
+ForExpr ::= ‘for’ (‘(’ Enumerators ‘)’ | ‘{’ Enumerators ‘}’) ForYield(enums, expr)
+ {nl} [‘yield’] Expr
+ | ‘for’ Enumerators (‘do’ Expr | ‘yield’ Expr) ForDo(enums, expr)
+Enumerators ::= Generator {semi Enumerator | Guard}
+Enumerator ::= Generator
+ | Guard
+ | Pattern1 ‘=’ Expr GenAlias(pat, expr)
+Generator ::= Pattern1 ‘<-’ Expr GenFrom(pat, expr)
+Guard ::= ‘if’ PostfixExpr
+
+CaseClauses ::= CaseClause { CaseClause } CaseDef(pat, guard?, block) // block starts at =>
+CaseClause ::= ‘case’ (Pattern [Guard] ‘=>’ Block | INT)
+
+Pattern ::= Pattern1 { ‘|’ Pattern1 } Alternative(pats)
+Pattern1 ::= PatVar ‘:’ RefinedType Bind(name, Typed(Ident(wildcard), tpe))
+ | Pattern2
+Pattern2 ::= [varid ‘@’] InfixPattern Bind(name, pat)
+InfixPattern ::= SimplePattern { id [nl] SimplePattern } InfixOp(pat, op, pat)
+SimplePattern ::= PatVar Ident(wildcard)
+ | Literal Bind(name, Ident(wildcard))
+ | ‘(’ [Patterns] ‘)’ Parens(pats) Tuple(pats)
+ | XmlPattern
+ | SimplePattern1 [TypeArgs] [ArgumentPatterns]
+SimplePattern1 ::= Path
+ | ‘{’ Block ‘}’
+ | SimplePattern1 ‘.’ id
+PatVar ::= varid
+ | ‘_’
+Patterns ::= Pattern {‘,’ Pattern}
+ArgumentPatterns ::= ‘(’ [Patterns] ‘)’ Apply(fn, pats)
+ | ‘(’ [Patterns ‘,’] Pattern2 ‘:’ ‘_’ ‘*’ ‘)’
+```
+
+### Type and Value Parameters
+```ebnf
+ClsTypeParamClause::= ‘[’ ClsTypeParam {‘,’ ClsTypeParam} ‘]’
+ClsTypeParam ::= {Annotation} [{Modifier} type] [‘+’ | ‘-’] TypeDef(Modifiers, name, tparams, bounds)
+ id [HkTypeParamClause] TypeParamBounds Bound(below, above, context)
+
+DefTypeParamClause::= ‘[’ DefTypeParam {‘,’ DefTypeParam} ‘]’
+DefTypeParam ::= {Annotation} id [HkTypeParamClause] TypeParamBounds
+
+TypTypeParamClause::= ‘[’ TypTypeParam {‘,’ TypTypeParam} ‘]’
+TypTypeParam ::= {Annotation} id [HkTypeParamClause] TypeBounds
+
+HkTypeParamClause ::= ‘[’ HkTypeParam {‘,’ HkTypeParam} ‘]’
+HkTypeParam ::= {Annotation} [‘+’ | ‘-’] (Id[HkTypeParamClause] | ‘_’)
+ TypeBounds
+
+ClsParamClauses ::= {ClsParamClause} [[nl] ‘(’ ‘implicit’ ClsParams ‘)’]
+ClsParamClause ::= [nl] ‘(’ [ClsParams] ‘)’
+ClsParams ::= ClsParam {‘,’ ClsParam}
+ClsParam ::= {Annotation} ValDef(mods, id, tpe, expr) -- point of mods on val/var
+ [{Modifier} (‘val’ | ‘var’) | ‘inline’] Param
+Param ::= id ‘:’ ParamType [‘=’ Expr]
+ | INT
+
+DefParamClauses ::= {DefParamClause} [[nl] ‘(’ ‘implicit’ DefParams ‘)’]
+DefParamClause ::= [nl] ‘(’ [DefParams] ‘)’
+DefParams ::= DefParam {‘,’ DefParam}
+DefParam ::= {Annotation} [‘inline’] Param ValDef(mods, id, tpe, expr) -- point of mods at id.
+```
+
+### Bindings and Imports
+```ebnf
+Bindings ::= ‘(’ Binding {‘,’ Binding} ‘)’
+Binding ::= (id | ‘_’) [‘:’ Type] ValDef(_, id, tpe, EmptyTree)
+
+Modifier ::= LocalModifier
+ | AccessModifier
+ | ‘override’
+LocalModifier ::= ‘abstract’
+ | ‘final’
+ | ‘sealed’
+ | ‘implicit’
+ | ‘lazy’
+AccessModifier ::= (‘private’ | ‘protected’) [AccessQualifier]
+AccessQualifier ::= ‘[’ (id | ‘this’) ‘]’
+
+Annotation ::= ‘@’ SimpleType {ParArgumentExprs} Apply(tpe, args)
+
+TemplateBody ::= [nl] ‘{’ [SelfType] TemplateStat {semi TemplateStat} ‘}’ (self, stats)
+TemplateStat ::= Import
+ | {Annotation [nl]} {Modifier} Def
+ | {Annotation [nl]} {Modifier} Dcl
+ | Expr1
+SelfType ::= id [‘:’ InfixType] ‘=>’ ValDef(_, name, tpt, _)
+ | ‘this’ ‘:’ InfixType ‘=>’
+
+Import ::= ‘import’ ImportExpr {‘,’ ImportExpr}
+ImportExpr ::= StableId ‘.’ (id | ‘_’ | ImportSelectors) Import(expr, sels)
+ImportSelectors ::= ‘{’ {ImportSelector ‘,’} (ImportSelector | ‘_’) ‘}’
+ImportSelector ::= id [‘=>’ id | ‘=>’ ‘_’] Ident(name), Pair(id, id)
+```
+
+### Declarations and Definitions
+```ebnf
+Dcl ::= ‘val’ ValDcl
+ | ‘var’ VarDcl
+ | ‘def’ DefDcl
+ | ‘type’ {nl} TypeDcl
+ | INT
+
+ValDcl ::= ids ‘:’ Type PatDef(_, ids, tpe, EmptyTree)
+VarDcl ::= ids ‘:’ Type PatDef(_, ids, tpe, EmptyTree)
+DefDcl ::= DefSig [‘:’ Type] DefDef(_, name, tparams, vparamss, tpe, EmptyTree)
+DefSig ::= id [DefTypeParamClause] DefParamClauses
+TypeDcl ::= id [TypTypeParamClause] [‘=’ Type] TypeDefTree(_, name, tparams, tpt)
+ | id [HkTypeParamClause] TypeBounds TypeDefTree(_, name, tparams, bounds)
+
+Def ::= ‘val’ PatDef
+ | ‘var’ VarDef
+ | ‘def’ DefDef
+ | ‘type’ {nl} TypeDcl
+ | TmplDef
+ | INT
+PatDef ::= Pattern2 {‘,’ Pattern2} [‘:’ Type] ‘=’ Expr PatDef(_, pats, tpe?, expr)
+VarDef ::= PatDef
+ | ids ‘:’ Type ‘=’ ‘_’
+DefDef ::= DefSig [‘:’ Type] ‘=’ Expr DefDef(_, name, tparams, vparamss, tpe, expr)
+ | DefSig [nl] ‘{’ Block ‘}’ DefDef(_, name, tparams, vparamss, tpe, Block)
+ | ‘this’ DefParamClause DefParamClauses DefDef(_, <init>, Nil, vparamss, EmptyTree, expr | Block)
+ (‘=’ ConstrExpr | [nl] ConstrBlock)
+
+TmplDef ::= ([‘case’] ‘class’ | ‘trait’) ClassDef
+ | [‘case’] ‘object’ ObjectDef
+ClassDef ::= id [ClsTypeParamClause] ClassDef(mods, name, tparams, templ)
+ [ConstrMods] ClsParamClauses TemplateOpt with DefDef(_, <init>, Nil, vparamss, EmptyTree, EmptyTree) as first stat
+ConstrMods ::= AccessModifier
+ | Annotation {Annotation} (AccessModifier | ‘this’)
+ObjectDef ::= id TemplateOpt ModuleDef(mods, name, template) // no constructor
+TemplateOpt ::= [‘extends’ Template | [nl] TemplateBody]
+Template ::= ConstrApps [TemplateBody] | TemplateBody Template(constr, parents, self, stats)
+ConstrApps ::= ConstrApp {‘with’ ConstrApp}
+ConstrApp ::= AnnotType {ArgumentExprs} Apply(tp, args)
+ConstrExpr ::= SelfInvocation
+ | ConstrBlock
+SelfInvocation ::= ‘this’ ArgumentExprs {ArgumentExprs}
+ConstrBlock ::= ‘{’ SelfInvocation {semi BlockStat} ‘}’
+
+TopStatSeq ::= TopStat {semi TopStat}
+TopStat ::= {Annotation [nl]} {Modifier} TmplDef
+ | Import
+ | Packaging
+ | PackageObject
+Packaging ::= ‘package’ QualId [nl] ‘{’ TopStatSeq ‘}’ Package(qid, stats)
+PackageObject ::= ‘package’ ‘object’ ObjectDef object with package in mods.
+
+CompilationUnit ::= {‘package’ QualId semi} TopStatSeq Package(qid, stats)
+```
diff --git a/docs/dotc-internals/core-data-structures.md b/docs/dotc-internals/core-data-structures.md
new file mode 100644
index 000000000..eddc3398c
--- /dev/null
+++ b/docs/dotc-internals/core-data-structures.md
@@ -0,0 +1,113 @@
+(The following is work in progress)
+
+## Symbols and SymDenotations
+
+ - why symbols are not enough: their contents change all the time
+ - they change themselvesSo a `Symbol
+
+ - reference: string + sig
+
+
+Dotc is different from most other compilers in that it is centered around the idea of
+maintaining views of various artifacts associated with code. These views are indexed
+by tne
+
+A symbol refers to a definition in a source program. Traditionally,
+ compilers store context-dependent data in a _symbol table_. The
+ symbol then is the central reference to address context-dependent
+ data. But for `dotc`'s requirements it turns out that symbols are
+ both too little and too much for this task.
+
+Too little: The attributes of a symbol depend on the phase. Examples:
+Types are gradually simplified by several phases. Owners are changed
+in phases `LambdaLift` (when methods are lifted out to an enclosing
+class) and Flatten (when all classes are moved to top level). Names
+are changed when private members need to be accessed from outside
+their class (for instance from a nested class or a class implementing
+a trait). So a functional compiler, a `Symbol` by itself met mean
+much. Instead we are more interested in the attributes of a symbol at
+a given phase.
+
+`dotc` has a concept for "attributes of a symbol at
+
+Too much: If a symbol is used to refer to a definition in another
+compilation unit, we get problems for incremental recompilation. The
+unit containing the symbol might be changed and recompiled, which
+might mean that the definition referred to by the symbol is deleted or
+changed. This leads to the problem of stale symbols that refer to
+definitions that no longer exist in this form. `scalac` tried to
+address this problem by _rebinding_ symbols appearing in certain cross
+module references, but it turned out to be too difficult to do this
+reliably for all kinds of references. `dotc` attacks the problem at
+the root instead. The fundamental problem is that symbols are too
+specific to serve as a cross-module reference in a system with
+incremental compilation. They refer to a particular definition, but
+that definition may not persist unchanged after an edit.
+
+`dotc` uses instead a different approach: A cross module reference is
+always type, either a `TermRef` or ` TypeRef`. A reference type contains
+a prefix type and a name. The definition the type refers to is established
+dynamically based on these fields.
+
+
+a system where sources can be recompiled at any instance,
+
+ the concept of a `Denotation`.
+
+ Since definitions are transformed by phases,
+
+
+The [Dotty project](https://github.com/lampepfl/dotty)
+is a platform to develop new technology for Scala
+tooling and to try out concepts of future Scala language versions.
+Its compiler is a new design intended to reflect the
+lessons we learned from work with the Scala compiler. A clean redesign
+today will let us iterate faster with new ideas in the future.
+
+Today we reached an important milestone: The Dotty compiler can
+compile itself, and the compiled compiler can act as a drop-in for the
+original one. This is what one calls a *bootstrap*.
+
+## Why is this important?
+
+The main reason is that this gives us a some validation of the
+*trustworthiness* of the compiler itself. Compilers are complex beasts,
+and many things can go wrong. By far the worst things that can go
+wrong are bugs where incorrect code is produced. It's not fun debugging code that looks perfectly
+fine, yet gets translated to something subtly wrong by the compiler.
+
+Having the compiler compile itself is a good test to demonstrate that
+the generated code has reached a certain level of quality. Not only is
+a compiler a large program (44k lines in the case of dotty), it is
+also one that exercises a large part of the language in quite
+intricate ways. Moreover, bugs in the code of a compiler don't tend to
+go unnoticed, precisely because every part of a compiler feeds into
+other parts and all together are necessary to produce a correct
+translation.
+
+## Are We Done Yet?
+
+Far from it! The compiler is still very rough. A lot more work is
+needed to
+
+ - make it more robust, in particular when analyzing incorrect programs,
+ - improve error messages and warnings,
+ - improve the efficiency of some of the generated code,
+ - embed it in external tools such as sbt, REPL, IDEs,
+ - remove restrictions on what Scala code can be compiled,
+ - help in migrating Scala code that will have to be changed.
+
+## What Are the Next Steps?
+
+Over the coming weeks and months, we plan to work on the following topics:
+
+ - Make snapshot releases.
+ - Get the Scala standard library to compile.
+ - Work on SBT integration of the compiler.
+ - Work on IDE support.
+ - Investigate the best way to obtaining a REPL.
+ - Work on the build infrastructure.
+
+If you want to get your hands dirty with any of this, now is a good moment to get involved!
+To get started: <https://github.com/lampepfl/dotty>.
+
diff --git a/docs/syntax-summary.txt b/docs/syntax-summary.txt
deleted file mode 100644
index 04e149de6..000000000
--- a/docs/syntax-summary.txt
+++ /dev/null
@@ -1,329 +0,0 @@
-% $Id: SyntaxSummary.tex 21104 2010-03-08 13:49:27Z odersky $
-
-\chapter{Scala Syntax Summary}\label{sec:syntax}
-\todo{introduce SeqPattern syntax}
-
-The lexical syntax of Scala is given by the following grammar in EBNF
-form.
-
-{\small
-\begin{lstlisting}
- upper ::= `A' | $\cdots$ | `Z' | `$\Dollar$' | `_' $\mbox{\rm\em and Unicode category Lu}$
- lower ::= `a' | $\cdots$ | `z' $\mbox{\rm\em and Unicode category Ll}$
- letter ::= upper | lower $\mbox{\rm\em and Unicode categories Lo, Lt, Nl}$
- digit ::= `0' | $\cdots$ | `9'
- opchar ::= $\mbox{\rm\em ``all other characters in \U{0020-007F} and Unicode}$
- $\mbox{\rm\em categories Sm, So except parentheses ([{}]) and periods''}$
-
- op ::= opchar {opchar}
- varid ::= lower idrest
- alphaid ::= upper idrest
- | varid
- plainid ::= alphaid
- | op
- id ::= plainid
- | `\`' stringLit `\`'
- | INT // interpolation id, only for quasi-quotes
- idrest ::= {letter | digit} [`_' op]
-
- integerLiteral ::= (decimalNumeral | hexNumera) [`L' | `l']
- decimalNumeral ::= `0' | nonZeroDigit {digit}
- hexNumeral ::= `0' `x' hexDigit {hexDigit}
- digit ::= `0' | nonZeroDigit
- nonZeroDigit ::= `1' | $\cdots$ | `9'
- octalDigit ::= `0' | $\cdots$ | `7'
-
- floatingPointLiteral
- ::= digit {digit} `.' {digit} [exponentPart] [floatType]
- | `.' digit {digit} [exponentPart] [floatType]
- | digit {digit} exponentPart [floatType]
- | digit {digit} [exponentPart] floatType
- exponentPart ::= (`E' | `e') [`+' | `-'] digit {digit}
- floatType ::= `F' | `f' | `D' | `d'
-
- booleanLiteral ::= `true' | `false'
-
- characterLiteral ::= `\'' printableChar `\''
- | `\'' charEscapeSeq `\''
-
- stringLiteral ::= `"' {stringElement} `"'
- | `"""' {[`"'] [`"'] char \ `"'} {`"'} `"""'
- stringElement ::= printableChar \ (`"' | `\')
- | charEscapeSeq
- charEscapeSeq ::= `\b' | `\n' | `\t' | `\f' | `\r' | `"' | `'' | `\\'
-
- processedStringLiteral
- ::= alphaid`"' {printableChar \ (`"' | `$') | escape} `"'
- | alphaid `"""' {[`"'] [`"'] char \ (`"' | `$') | escape} {`"'} `"""'
- escape ::= `$$' \comment{$}
- | `$' letter { letter | digit }
- | `{' Block [`;' whiteSpace stringFormat whiteSpace] `}'
- stringFormat ::= {printableChar \ (`"' | `}' | ` ' | `\t' | `\n')}
- whiteSpace ::= {` ' | `\t'}
-
- symbolLiteral ::= `'' plainid
-
- comment ::= `/*' $\mbox{\rm\em ``any sequence of characters''}$ `*/'
- | `//' $\mbox{\rm\em ``any sequence of characters up to end of line''}$
-
- nl ::= $\mbox{\rm\em ``new line character''}$
- semi ::= `;' | nl {nl}
-\end{lstlisting}}
-
-The context-free syntax of Scala is given by the following EBNF
-grammar.
-
-{\small
-\begin{lstlisting}
- SimpleLiteral ::= [`-'] integerLiteral
- | [`-'] floatingPointLiteral
- | booleanLiteral
- | characterLiteral
- | stringLiteral
- Literal ::= SimpleLiteral
- | processedStringLiteral
- | symbolLiteral
- | `null'
-
- QualId ::= id {`.' id}
- ids ::= id {`,' id}
-
- Path ::= StableId
- | [id `.'] `this'
- StableId ::= id
- | Path `.' id
- | [id '.'] `super' [ClassQualifier] `.' id
- ClassQualifier ::= `[' id `]'
-
- Type ::= FunArgTypes `=>' Type Function(ts, t)
- | HkTypeParamClause `=>' Type TypeLambda(ps, t)
- | InfixType
- FunArgTypes ::= InfixType
- | `(' [ FunArgType {`,' FunArgType } ] `)'
- InfixType ::= RefinedType {id [nl] RefinedType} InfixOp(t1, op, t2)
- RefinedType ::= WithType {[nl] Refinement} RefinedTypeTree(t, ds)
- WithType ::= AnnotType {`with' AnnotType} (deprecated)
- AnnotType ::= SimpleType {Annotation} Annotated(t, annot)
- SimpleType ::= SimpleType (TypeArgs | NamedTypeArgs) AppliedTypeTree(t, args)
- | SimpleType `#' id Select(t, name)
- | StableId
- | Path `.' `type' SingletonTypeTree(p)
- | `(' ArgTypes ')' Tuple(ts)
- | `_' TypeBounds
- | Refinement RefinedTypeTree(EmptyTree, refinement)
- | SimpleLiteral SingletonTypeTree(l)
- ArgTypes ::= Type {`,' Type}
- | NamedTypeArg {`,' NamedTypeArg }
- FunArgType ::= Type
- | `=>' Type PrefixOp(=>, t)
- ParamType ::= [`=>'] ParamValueType
- ParamValueType ::= Type [`*'] PostfixOp(t, "*")
- TypeArgs ::= `[' ArgTypes `]' ts
- NamedTypeArg ::= id `=' Type NamedArg(id, t)
- NamedTypeArgs ::= `[' NamedTypeArg {`,' NamedTypeArg} `]' nts
- Refinement ::= `{' [Dcl] {semi [Dcl]} `}' ds
- TypeBounds ::= [`>:' Type] [`<: Type] | INT TypeBoundsTree(lo, hi)
- TypeParamBounds ::= TypeBounds {`<%' Type} {`:' Type} ContextBounds(typeBounds, tps)
-
- Expr ::= FunParams `=>' Expr Function(args, expr), Function(ValDef([implicit], id, TypeTree(), EmptyTree), expr)
- FunParams ::= Bindings
- | [`implicit'] id
- | `_'
- ExprInParens ::= PostfixExpr `:' Type
- | Expr
- BlockResult ::= (FunParams | [`implicit'] id `:' InfixType) `=>' Block
- | Expr1
- Expr1 ::= `if' `(' Expr `)' {nl} Expr [[semi] else Expr] If(Parens(cond), thenp, elsep?)
- | `if' Expr `then' Expr [[semi] else Expr] If(cond, thenp, elsep?)
- | `while' `(' Expr `)' {nl} Expr WhileDo(Parens(cond), body)
- | `while' Expr `do' Expr WhileDo(cond, body)
- | `do' Expr [semi] `while' Expr DoWhile(expr, cond)
- | `try' Expr Catches [`finally' Expr] Try(expr, catches, expr?)
- | `try' Expr [`finally' Expr] Try(expr, Nil, expr?)
- | `throw' Expr Throw(expr)
- | `return' [Expr] Return(expr?)
- | ForExpr
- | [SimpleExpr `.'] id `=' Expr Assign(expr, expr)
- | SimpleExpr1 ArgumentExprs `=' Expr Assign(expr, expr)
- | PostfixExpr [Ascription]
- | PostfixExpr `match' `{' CaseClauses `}' Match(expr, cases) -- point on match
- Ascription ::= `:' InfixType Typed(expr, tp)
- | `:' Annotation {Annotation} Typed(expr, Annotated(EmptyTree, annot)*)
- Catches ::= `catch' Expr
- PostfixExpr ::= InfixExpr [id] PostfixOp(expr, op)
- InfixExpr ::= PrefixExpr
- | InfixExpr id [nl] InfixExpr InfixOp(expr, op, expr)
- PrefixExpr ::= [`-' | `+' | `~' | `!'] SimpleExpr PrefixOp(expr, op)
- SimpleExpr ::= `new' Template New(templ)
- | BlockExpr
- | SimpleExpr1 [`_'] PostfixOp(expr, _)
- SimpleExpr1 ::= Literal
- | Path
- | `_'
- | `(' ExprsInParens2 `)' Parens(exprs)
- | SimpleExpr `.' id Select(expr, id)
- | SimpleExpr (TypeArgs | NamedTypeArgs) TypeApply(expr, args)
- | SimpleExpr1 ArgumentExprs Apply(expr, args)
- | XmlExpr
- ExprsInParens ::= ExprInParens {`,' ExprInParens}
- ParArgumentExprs ::= `(' [ExprsInParens] `)' exprs
- | `(' [ExprsInParens `,'] PostfixExpr `:' `_' `*' ')' exprs :+ Typed(expr, Ident(wildcardStar))
- ArgumentExprs ::= ParArgumentExprs
- | [nl] BlockExpr
- BlockExpr ::= `{' CaseClauses `}' Match(EmptyTree, cases)
- | `{' Block `}' block // starts at {
- Block ::= {BlockStat semi} [BlockResult] Block(stats, expr?)
- BlockStat ::= Import
- | {Annotation} [`implicit' | `lazy'] Def
- | {Annotation} {LocalModifier} TmplDef
- | Expr1
- |
- ResultExpr ::= Expr1
- | (Bindings | ([`implicit'] id | `_') `:' ) `=>' Block
- Function(args, block) // block starts at =>
- ForExpr ::= `for' (`(' Enumerators `)' | `{' Enumerators `}') ForYield(enums, expr)
- {nl} [`yield'] Expr ForDo(enums, expr)
- | `for' Enumerators (`do' Expr | `yield' Expr)
-
- Enumerators ::= Generator {semi Enumerator | Guard}
- Enumerator ::= Generator
- | Guard
- | Pattern1 `=' Expr GenAlias(pat, expr)
- Generator ::= Pattern1 `<-' Expr GenFrom(pat, expr)
- Guard ::= `if' PostfixExpr
-
- CaseClauses ::= CaseClause { CaseClause }
- CaseClause ::= `case' (Pattern [Guard] `=>' Block | INT) CaseDef(pat, guard?, block) // block starts at =>
-
- Pattern ::= Pattern1 { `|' Pattern1 } Alternative(pats)
- Pattern1 ::= PatVar `:' RefinedType Bind(name, Typed(Ident(wildcard), tpe))
- | Pattern2
- Pattern2 ::= [varid `@'] InfixPattern Bind(name, pat)
- InfixPattern ::= SimplePattern { id [nl] SimplePattern } InfixOp(pat, op, pat)
- SimplePattern ::= PatVar Ident(wildcard)
- | Literal Bind(name, Ident(wildcard))
- | `(' [Patterns] `)' Parens(pats) Tuple(pats)
- | XmlPattern
- | SimplePattern1 [TypeArgs] [ArgumentPatterns]
- SimplePattern1 ::= Path
- | `{' Block `}'
- | SimplePattern1 `.' id
- PatVar ::= varid
- | `_'
- Patterns ::= Pattern {`,' Pattern}
- ArgumentPatterns ::= `(' [Patterns] `)' Apply(fn, pats)
- | `(' [Patterns `,'] Pattern2 `:' `_' `*' ')
-
- ClsTypeParamClause::= `[' ClsTypeParam {`,' ClsTypeParam} `]'
- ClsTypeParam ::= {Annotation} [{Modifier} type] [`+' | `-'] TypeDef(Modifiers, name, tparams, bounds)
- id [HkTypeParamClause] TypeParamBounds Bound(below, above, context)
-
- DefTypeParamClause::= `[' DefTypeParam {`,' DefTypeParam} `]'
- DefTypeParam ::= {Annotation} id [HkTypeParamClause] TypeParamBounds
-
- TypTypeParamCaluse::= `[' TypTypeParam {`,' TypTypeParam} `]'
- TypTypeParam ::= {Annotation} id [HkTypeParamClause] TypeBounds
-
- HkTypeParamClause ::= `[' HkTypeParam {`,' HkTypeParam} `]'
- HkTypeParam ::= {Annotation} ['+' | `-'] (Id[HkTypeParamClause] | `_')
- TypeBounds
-
- ClsParamClauses ::= {ClsParamClause} [[nl] `(' `implicit' ClsParams `)']
- ClsParamClause ::= [nl] `(' [ClsParams] ')'
- ClsParams ::= ClsParam {`' ClsParam}
- ClsParam ::= {Annotation}
- [{Modifier} (`val' | `var') | `inline'] Param ValDef(mods, id, tpe, expr) -- point of mods on val/var
- Param ::= id `:' ParamType [`=' Expr]
- | INT
-
- DefParamClauses ::= {DefParamClause} [[nl] `(' `implicit' DefParams `)']
- DefParamClause ::= [nl] `(' [DefParams] ')'
- DefParams ::= DefParam {`,' DefParam}
- DefParam ::= {Annotation} [`inline'] Param ValDef(mods, id, tpe, expr) -- point of mods at id.
-
- Bindings ::= `(' Binding {`,' Binding `)' bindings
- Binding ::= (id | `_') [`:' Type] ValDef(_, id, tpe, EmptyTree)
-
- Modifier ::= LocalModifier
- | AccessModifier
- | `override'
- LocalModifier ::= `abstract'
- | `final'
- | `sealed'
- | `implicit'
- | `lazy'
- AccessModifier ::= (`private' | `protected') [AccessQualifier]
- AccessQualifier ::= `[' (id | `this') `]'
-
- Annotation ::= `@' SimpleType {ParArgumentExprs} Apply(tpe, args)
-
- TemplateBody ::= [nl] `{' [SelfType] TemplateStat {semi TemplateStat} `} (self, stats)
- TemplateStat ::= Import
- | {Annotation [nl]} {Modifier} Def
- | {Annotation [nl]} {Modifier} Dcl
- | Expr1
- |
- SelfType ::= id [`:' InfixType] `=>' ValDef(_, name, tpt, _)
- | `this' `:' InfixType `=>
-
- Import ::= `import' ImportExpr {`,' ImportExpr}
- ImportExpr ::= StableId `.' (id | `_' | ImportSelectors) Import(expr, sels)
- ImportSelectors ::= `{' {ImportSelector `,'} (ImportSelector | `_') `}'
- ImportSelector ::= id [`=>' id | `=>' `_'] Ident(name), Pair(id, id)
-
- Dcl ::= `val' ValDcl
- | `var' VarDcl
- | `def' DefDcl
- | `type' {nl} TypeDcl
- | INT
-
- ValDcl ::= ids `:' Type PatDef(_, ids, tpe, EmptyTree)
- VarDcl ::= ids `:' Type PatDef(_, ids, tpe, EmptyTree)
- DefDcl ::= DefSig [`:' Type] DefDef(_, name, tparams, vparamss, tpe, EmptyTree)
- DefSig ::= id [DefTypeParamClause] DefParamClauses
- TypeDcl ::= id [TypTypeParamClause] ['=' Type] TypeDefTree(_, name, tparams, tpt)
- | id [HkTypeParamClause] TypeBounds TypeDefTree(_, name, tparams, bounds)
-
- Def ::= `val' PatDef
- | `var' VarDef
- | `def' DefDef
- | `type' {nl} TypeDcl
- | TmplDef
- | INT
- PatDef ::= Pattern2 {`,' Pattern2} [`:' Type] `=' Expr PatDef(_, pats, tpe?, expr)
- VarDef ::= PatDef
- | ids `:' Type `=' `_'
- DefDef ::= DefSig [`:' Type] `=' Expr DefDef(_, name, tparams, vparamss, tpe, expr)
- | DefSig [nl] `{' Block `}' DefDef(_, name, tparams, vparamss, tpe, Block)
- | `this' DefParamClause DefParamClauses DefDef(_, <init>, Nil, vparamss, EmptyTree, expr | Block)
- (`=' ConstrExpr | [nl] ConstrBlock)
-
- TmplDef ::= ([`case'] `class' | `trait') ClassDef
- | [`case'] `object' ObjectDef
- ClassDef ::= id [ClsTypeParamClause] ClassDef(mods, name, tparams, templ) //
- [ConstrMods] ClsParamClauses TemplateOpt with DefDef(_, <init>, Nil, vparamss, EmptyTree, EmptyTree) as first stat
- ConstrMods ::= AccessModifier
- | Annotation {Annotation} (AccessModifier | `this')
- ObjectDef ::= id TemplateOpt ModuleDef(mods, name, template) // no constructor
- TemplateOpt ::= [`extends' Template | [nl] TemplateBody]
- Template ::= ConstrApps [TemplateBody] | TemplateBody Template(constr, parents, self, stats)
- ConstrApps ::= ConstrApp {`with' ConstrApp}
- ConstrApp ::= AnnotType {ArgumentExprs} Apply(tp, args)
-
- ConstrExpr ::= SelfInvocation
- | ConstrBlock
- ConstrBlock ::= `{' SelfInvocation {semi BlockStat} `}'
- SelfInvocation ::= `this' ArgumentExprs {ArgumentExprs}
-
- TopStatSeq ::= TopStat {semi TopStat}
- TopStat ::= {Annotation [nl]} {Modifier} TmplDef
- | Import
- | Packaging
- | PackageObject
- |
- Packaging ::= `package' QualId [nl] `{' TopStatSeq `}' Package(qid, stats)
- PackageObject ::= `package' `object' ObjectDef object with package in mods.
-
- CompilationUnit ::= {`package' QualId semi} TopStatSeq Package(qid, stats)
-\end{lstlisting}
-}
diff --git a/library/src/dotty/Show.scala b/library/src/dotty/Show.scala
new file mode 100644
index 000000000..2feeb29ef
--- /dev/null
+++ b/library/src/dotty/Show.scala
@@ -0,0 +1,102 @@
+package dotty
+
+import scala.annotation.implicitNotFound
+
+@implicitNotFound("No member of type class Show could be found for ${T}")
+trait Show[-T] {
+ def show(t: T): String
+}
+
+/** Ideally show would only contain `defaultShow` and the pimped generic class,
+ * but since we can't change the current stdlib, we're stuck with providing
+ * default instances in this object
+ */
+object Show {
+ private[this] val defaultShow: Show[Any] = new Show[Any] {
+ def show(x: Any) = x.toString
+ }
+
+ /** This class implements pimping of all types to provide a show method.
+ * Currently it is quite permissive, if there's no instance of `Show[T]` for
+ * any `T`, we default to `T#toString`.
+ */
+ implicit class ShowValue[V](val v: V) extends AnyVal {
+ def show(implicit ev: Show[V] = defaultShow): String =
+ ev.show(v)
+ }
+
+ implicit val stringShow: Show[String] = new Show[String] {
+ // From 2.12 spec, `charEscapeSeq`:
+ // ‘\‘ (‘b‘ | ‘t‘ | ‘n‘ | ‘f‘ | ‘r‘ | ‘"‘ | ‘'‘ | ‘\‘)
+ def show(str: String) =
+ "\"" + {
+ val sb = new StringBuilder
+ str.foreach {
+ case '\b' => sb.append("\\b")
+ case '\t' => sb.append("\\t")
+ case '\n' => sb.append("\\n")
+ case '\f' => sb.append("\\f")
+ case '\r' => sb.append("\\r")
+ case '\'' => sb.append("\\'")
+ case '\"' => sb.append("\\\"")
+ case c => sb.append(c)
+ }
+ sb.toString
+ } + "\""
+ }
+
+ implicit val intShow: Show[Int] = new Show[Int] {
+ def show(i: Int) = i.toString
+ }
+
+ implicit val floatShow: Show[Float] = new Show[Float] {
+ def show(f: Float) = f + "f"
+ }
+
+ implicit val doubleShow: Show[Double] = new Show[Double] {
+ def show(d: Double) = d.toString
+ }
+
+ implicit val charShow: Show[Char] = new Show[Char] {
+ def show(c: Char) = "'" + (c match {
+ case '\b' => "\\b"
+ case '\t' => "\\t"
+ case '\n' => "\\n"
+ case '\f' => "\\f"
+ case '\r' => "\\r"
+ case '\'' => "\\'"
+ case '\"' => "\\\""
+ case c => c
+ }) + "'"
+ }
+
+ implicit def showList[T](implicit st: Show[T]): Show[List[T]] = new Show[List[T]] {
+ def show(xs: List[T]) =
+ if (xs.isEmpty) "Nil"
+ else "List(" + xs.map(_.show).mkString(", ") + ")"
+ }
+
+ implicit val showNil: Show[Nil.type] = new Show[Nil.type] {
+ def show(xs: Nil.type) = "Nil"
+ }
+
+ implicit def showOption[T](implicit st: Show[T]): Show[Option[T]] = new Show[Option[T]] {
+ def show(ot: Option[T]): String = ot match {
+ case Some(t) => "Some("+ st.show(t) + ")"
+ case none => "None"
+ }
+ }
+
+ implicit val showNone: Show[None.type] = new Show[None.type] {
+ def show(n: None.type) = "None"
+ }
+
+ implicit def showMap[K,V](implicit sk: Show[K], sv: Show[V]): Show[Map[K,V]] = new Show[Map[K,V]] {
+ def show(m: Map[K, V]) =
+ "Map(" + m.map { case (k, v) => sk.show(k) + " -> " + sv.show(v) } .mkString (", ") + ")"
+ }
+
+ implicit def showMapOfNothing: Show[Map[Nothing,Nothing]] = new Show[Map[Nothing,Nothing]] {
+ def show(m: Map[Nothing, Nothing]) = m.toString
+ }
+}
diff --git a/library/src/scala/Function23.scala b/library/src/scala/Function23.scala
deleted file mode 100644
index 254772d53..000000000
--- a/library/src/scala/Function23.scala
+++ /dev/null
@@ -1,21 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2002-2013, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-package scala
-
-
-/** A function of 23 parameters. Used as a temporary fix until arity limit is dropped.
- *
- */
-trait Function23[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, -T18, -T19, -T20, -T21, -T22, -T23, +R] extends AnyRef { self =>
- /** Apply the body of this function to the arguments.
- * @return the result of function application.
- */
- def apply(v1: T1, v2: T2, v3: T3, v4: T4, v5: T5, v6: T6, v7: T7, v8: T8, v9: T9, v10: T10, v11: T11, v12: T12, v13: T13, v14: T14, v15: T15, v16: T16, v17: T17, v18: T18, v19: T19, v20: T20, v21: T21, v22: T22, v23: T23): R
-
- override def toString() = "<function23>"
-}
diff --git a/library/src/scala/Function24.scala b/library/src/scala/Function24.scala
deleted file mode 100644
index 8af8ed995..000000000
--- a/library/src/scala/Function24.scala
+++ /dev/null
@@ -1,21 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2002-2013, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-package scala
-
-
-/** A function of 24 parameters. Used as a temporary fix until arity limit is dropped.
- *
- */
-trait Function24[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, -T18, -T19, -T20, -T21, -T22, -T23, -T24, +R] extends AnyRef { self =>
- /** Apply the body of this function to the arguments.
- * @return the result of function application.
- */
- def apply(v1: T1, v2: T2, v3: T3, v4: T4, v5: T5, v6: T6, v7: T7, v8: T8, v9: T9, v10: T10, v11: T11, v12: T12, v13: T13, v14: T14, v15: T15, v16: T16, v17: T17, v18: T18, v19: T19, v20: T20, v21: T21, v22: T22, v23: T23, v24: T24): R
-
- override def toString() = "<function24>"
-}
diff --git a/library/src/scala/Function25.scala b/library/src/scala/Function25.scala
deleted file mode 100644
index 6df740b5b..000000000
--- a/library/src/scala/Function25.scala
+++ /dev/null
@@ -1,21 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2002-2013, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-package scala
-
-
-/** A function of 25 parameters. Used as a temporary fix until arity limit is dropped.
- *
- */
-trait Function25[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, -T18, -T19, -T20, -T21, -T22, -T23, -T24, -T25, +R] extends AnyRef { self =>
- /** Apply the body of this function to the arguments.
- * @return the result of function application.
- */
- def apply(v1: T1, v2: T2, v3: T3, v4: T4, v5: T5, v6: T6, v7: T7, v8: T8, v9: T9, v10: T10, v11: T11, v12: T12, v13: T13, v14: T14, v15: T15, v16: T16, v17: T17, v18: T18, v19: T19, v20: T20, v21: T21, v22: T22, v23: T23, v24: T24, v25: T25): R
-
- override def toString() = "<function25>"
-}
diff --git a/library/src/scala/Function26.scala b/library/src/scala/Function26.scala
deleted file mode 100644
index 5daccb6f0..000000000
--- a/library/src/scala/Function26.scala
+++ /dev/null
@@ -1,20 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2002-2013, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-package scala
-
-/** A function of 26 parameters. Used as a temporary fix until arity limit is dropped.
- *
- */
-trait Function26[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, -T18, -T19, -T20, -T21, -T22, -T23, -T24, -T25, -T26, +R] extends AnyRef { self =>
- /** Apply the body of this function to the arguments.
- * @return the result of function application.
- */
- def apply(v1: T1, v2: T2, v3: T3, v4: T4, v5: T5, v6: T6, v7: T7, v8: T8, v9: T9, v10: T10, v11: T11, v12: T12, v13: T13, v14: T14, v15: T15, v16: T16, v17: T17, v18: T18, v19: T19, v20: T20, v21: T21, v22: T22, v23: T23, v24: T24, v25: T25, v26: T26): R
-
- override def toString() = "<function26>"
-}
diff --git a/library/src/scala/Function27.scala b/library/src/scala/Function27.scala
deleted file mode 100644
index daebd3ed4..000000000
--- a/library/src/scala/Function27.scala
+++ /dev/null
@@ -1,20 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2002-2013, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-package scala
-
-/** A function of 27 parameters. Used as a temporary fix until arity limit is dropped.
- *
- */
-trait Function27[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, -T18, -T19, -T20, -T21, -T22, -T23, -T24, -T25, -T26, -T27, +R] extends AnyRef { self =>
- /** Apply the body of this function to the arguments.
- * @return the result of function application.
- */
- def apply(v1: T1, v2: T2, v3: T3, v4: T4, v5: T5, v6: T6, v7: T7, v8: T8, v9: T9, v10: T10, v11: T11, v12: T12, v13: T13, v14: T14, v15: T15, v16: T16, v17: T17, v18: T18, v19: T19, v20: T20, v21: T21, v22: T22, v23: T23, v24: T24, v25: T25, v26: T26, v27: T27): R
-
- override def toString() = "<function27>"
-}
diff --git a/library/src/scala/Function28.scala b/library/src/scala/Function28.scala
deleted file mode 100644
index 82912caea..000000000
--- a/library/src/scala/Function28.scala
+++ /dev/null
@@ -1,20 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2002-2013, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-package scala
-
-/** A function of 28 parameters. Used as a temporary fix until arity limit is dropped.
- *
- */
-trait Function28[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, -T18, -T19, -T20, -T21, -T22, -T23, -T24, -T25, -T26, -T27, -T28, +R] extends AnyRef { self =>
- /** Apply the body of this function to the arguments.
- * @return the result of function application.
- */
- def apply(v1: T1, v2: T2, v3: T3, v4: T4, v5: T5, v6: T6, v7: T7, v8: T8, v9: T9, v10: T10, v11: T11, v12: T12, v13: T13, v14: T14, v15: T15, v16: T16, v17: T17, v18: T18, v19: T19, v20: T20, v21: T21, v22: T22, v23: T23, v24: T24, v25: T25, v26: T26, v27: T27, v28: T28): R
-
- override def toString() = "<function28>"
-}
diff --git a/library/src/scala/Function29.scala b/library/src/scala/Function29.scala
deleted file mode 100644
index 6dabf2051..000000000
--- a/library/src/scala/Function29.scala
+++ /dev/null
@@ -1,20 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2002-2013, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-package scala
-
-/** A function of 29 parameters. Used as a temporary fix until arity limit is dropped.
- *
- */
-trait Function29[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, -T18, -T19, -T20, -T21, -T22, -T23, -T24, -T25, -T26, -T27, -T28, -T29, +R] extends AnyRef { self =>
- /** Apply the body of this function to the arguments.
- * @return the result of function application.
- */
- def apply(v1: T1, v2: T2, v3: T3, v4: T4, v5: T5, v6: T6, v7: T7, v8: T8, v9: T9, v10: T10, v11: T11, v12: T12, v13: T13, v14: T14, v15: T15, v16: T16, v17: T17, v18: T18, v19: T19, v20: T20, v21: T21, v22: T22, v23: T23, v24: T24, v25: T25, v26: T26, v27: T27, v28: T28, v29: T29): R
-
- override def toString() = "<function29>"
-}
diff --git a/library/src/scala/Function30.scala b/library/src/scala/Function30.scala
deleted file mode 100644
index 20fd970dd..000000000
--- a/library/src/scala/Function30.scala
+++ /dev/null
@@ -1,20 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2002-2013, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-package scala
-
-/** A function of 30 parameters. Used as a temporary fix until arity limit is dropped.
- *
- */
-trait Function30[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, -T18, -T19, -T20, -T21, -T22, -T23, -T24, -T25, -T26, -T27, -T28, -T29, -T30, +R] extends AnyRef { self =>
- /** Apply the body of this function to the arguments.
- * @return the result of function application.
- */
- def apply(v1: T1, v2: T2, v3: T3, v4: T4, v5: T5, v6: T6, v7: T7, v8: T8, v9: T9, v10: T10, v11: T11, v12: T12, v13: T13, v14: T14, v15: T15, v16: T16, v17: T17, v18: T18, v19: T19, v20: T20, v21: T21, v22: T22, v23: T23, v24: T24, v25: T25, v26: T26, v27: T27, v28: T28, v29: T29, v30: T30): R
-
- override def toString() = "<function30>"
-}
diff --git a/library/src/scala/FunctionXXL.scala b/library/src/scala/FunctionXXL.scala
new file mode 100644
index 000000000..25e7af609
--- /dev/null
+++ b/library/src/scala/FunctionXXL.scala
@@ -0,0 +1,9 @@
+package scala
+
+/** A function with all parameters grouped in an array. */
+trait FunctionXXL {
+
+ def apply(xs: Array[Object]): Object
+
+ override def toString() = "<functionXXL>"
+}
diff --git a/library/test/dotty/ShowTests.scala b/library/test/dotty/ShowTests.scala
new file mode 100644
index 000000000..7230106d5
--- /dev/null
+++ b/library/test/dotty/ShowTests.scala
@@ -0,0 +1,69 @@
+package dotty
+
+import org.junit.Test
+import org.junit.Assert._
+
+class ShowTests {
+ import Show._
+
+ @Test def showString = {
+ assertEquals("\"\\thello world!\"", "\thello world!".show)
+ assertEquals("\"\\nhello world!\"", "\nhello world!".show)
+ assertEquals("\"\\rhello world!\"", "\rhello world!".show)
+ assertEquals("\"\\b\\t\\n\\f\\r\\\'\\\"\"", "\b\t\n\f\r\'\"".show)
+ }
+
+ @Test def showFloat = {
+ assertEquals("1.0f", 1.0f.show)
+ assertEquals("1.0f", 1.0F.show)
+ }
+
+ @Test def showDouble = {
+ assertEquals("1.0", 1.0d.show)
+ assertEquals("1.0", 1.0.show)
+ }
+
+ @Test def showChar = {
+ assertEquals("'\\b'", '\b'.show)
+ assertEquals("'\\t'", '\t'.show)
+ assertEquals("'\\n'", '\n'.show)
+ assertEquals("'\\f'", '\f'.show)
+ assertEquals("'\\r'", '\r'.show)
+ assertEquals("'\\''", '\''.show)
+ assertEquals("'\\\"'", '\"'.show)
+ }
+
+ @Test def showCar = {
+ case class Car(model: String, manufacturer: String, year: Int)
+ implicit val showCar = new Show[Car] {
+ def show(c: Car) =
+ "Car(" + c.model.show + ", " + c.manufacturer.show + ", " + c.year.show + ")"
+ }
+
+ case class Shop(xs: List[Car], name: String)
+ implicit val showShop = new Show[Shop] {
+ def show(sh: Shop) =
+ "Shop(" + sh.xs.show + ", " + sh.name.show + ")"
+ }
+
+ assertEquals("Car(\"Mustang\", \"Ford\", 1967)", Car("Mustang", "Ford", 1967).show)
+ }
+
+ @Test def showOptions = {
+ assertEquals("None", None.show)
+ assertEquals("None", (None: Option[String]).show)
+ assertEquals("Some(\"hello opt\")", Some("hello opt").show)
+ }
+
+ @Test def showMaps = {
+ val mp = scala.collection.immutable.Map("str1" -> "val1", "str2" -> "val2")
+ assertEquals("Map(\"str1\" -> \"val1\", \"str2\" -> \"val2\")", mp.show)
+ }
+
+ @Test def withoutShow = {
+ case class Car(model: String, manufacturer: String, year: Int)
+
+ assertEquals("Car(Mustang,Ford,1967)", Car("Mustang", "Ford", 1967).show)
+ assertEquals("Map()", Map().show)
+ }
+}
diff --git a/project/Build.scala b/project/Build.scala
index d6d0fdd91..99a6c5077 100644
--- a/project/Build.scala
+++ b/project/Build.scala
@@ -11,7 +11,7 @@ import sbt.Package.ManifestAttributes
object DottyBuild extends Build {
- val baseVersion = "0.1"
+ val baseVersion = "0.1.1"
val isNightly = sys.env.get("NIGHTLYBUILD") == Some("yes")
val jenkinsMemLimit = List("-Xmx1500m")
@@ -96,7 +96,8 @@ object DottyBuild extends Build {
// this is only necessary for compatibility with sbt which currently hardcodes the "dotty" artifact name
lazy val dotty = project.in(file(".")).
// FIXME: we do not aggregate `bin` because its tests delete jars, thus breaking other tests
- aggregate(`dotty-interfaces`, `dotty-library`, `dotty-compiler`, dottySbtBridgeRef, `scala-library`).
+ aggregate(`dotty-interfaces`, `dotty-library`, `dotty-compiler`, dottySbtBridgeRef,
+ `scala-library`, `scala-compiler`, `scala-reflect`, `scalap`).
dependsOn(`dotty-compiler`).
dependsOn(`dotty-library`).
settings(
@@ -375,9 +376,11 @@ object DottyBuild extends Build {
settings(
libraryDependencies ++= Seq(
"org.scala-lang" % "scala-reflect" % scalaVersion.value,
- "org.scala-lang" % "scala-library" % scalaVersion.value
+ "org.scala-lang" % "scala-library" % scalaVersion.value,
+ "com.novocode" % "junit-interface" % "0.11" % "test"
)
- )
+ ).
+ settings(publishing)
// until sbt/sbt#2402 is fixed (https://github.com/sbt/sbt/issues/2402)
lazy val cleanSbtBridge = TaskKey[Unit]("cleanSbtBridge", "delete dotty-sbt-bridge cache")
@@ -412,12 +415,6 @@ object DottyBuild extends Build {
"org.scala-sbt" % "api" % sbtVersion.value % "test",
"org.specs2" %% "specs2" % "2.3.11" % "test"
),
- version := {
- if (isNightly)
- "0.1.1-" + VersionUtil.commitDate + "-" + VersionUtil.gitHash + "-NIGHTLY"
- else
- "0.1.1-SNAPSHOT"
- },
// The sources should be published with crossPaths := false since they
// need to be compiled by the project using the bridge.
crossPaths := false,
@@ -453,13 +450,13 @@ object DottyInjectedPlugin extends AutoPlugin {
override def trigger = allRequirements
override val projectSettings = Seq(
- scalaVersion := "0.1-SNAPSHOT",
+ scalaVersion := "0.1.1-SNAPSHOT",
scalaOrganization := "ch.epfl.lamp",
scalacOptions += "-language:Scala2",
scalaBinaryVersion := "2.11",
autoScalaLibrary := false,
libraryDependencies ++= Seq("org.scala-lang" % "scala-library" % "2.11.5"),
- scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % "0.1.1-SNAPSHOT" % "component").sources()
+ scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % scalaVersion.value % "component").sources()
)
}
""")
@@ -553,11 +550,41 @@ object DottyInjectedPlugin extends AutoPlugin {
}
)
- lazy val `scala-library` = project
- .settings(
- libraryDependencies += "org.scala-lang" % "scala-library" % scalaVersion.value
- )
- .settings(publishing)
+
+ // Dummy scala-library artefact. This is useful because sbt projects
+ // automatically depend on scalaOrganization.value % "scala-library" % scalaVersion.value
+ lazy val `scala-library` = project.
+ dependsOn(`dotty-library`).
+ settings(
+ crossPaths := false
+ ).
+ settings(publishing)
+
+ // sbt >= 0.13.12 will automatically rewrite transitive dependencies on
+ // any version in any organization of scala{-library,-compiler,-reflect,p}
+ // to have organization `scalaOrganization` and version `scalaVersion`
+ // (see https://github.com/sbt/sbt/pull/2634).
+ // This means that we need to provide dummy artefacts for these projects,
+ // otherwise users will get compilation errors if they happen to transitively
+ // depend on one of these projects.
+ lazy val `scala-compiler` = project.
+ settings(
+ crossPaths := false,
+ libraryDependencies := Seq(scalaCompiler)
+ ).
+ settings(publishing)
+ lazy val `scala-reflect` = project.
+ settings(
+ crossPaths := false,
+ libraryDependencies := Seq("org.scala-lang" % "scala-reflect" % scalaVersion.value)
+ ).
+ settings(publishing)
+ lazy val `scalap` = project.
+ settings(
+ crossPaths := false,
+ libraryDependencies := Seq("org.scala-lang" % "scalap" % scalaVersion.value)
+ ).
+ settings(publishing)
lazy val publishing = Seq(
publishMavenStyle := true,
diff --git a/sbt-bridge/sbt-test/compilerReporter/simple/project/DottyInjectedPlugin.scala b/sbt-bridge/sbt-test/compilerReporter/simple/project/DottyInjectedPlugin.scala
index ec22870f4..ecfbd69b3 100644
--- a/sbt-bridge/sbt-test/compilerReporter/simple/project/DottyInjectedPlugin.scala
+++ b/sbt-bridge/sbt-test/compilerReporter/simple/project/DottyInjectedPlugin.scala
@@ -6,12 +6,12 @@ object DottyInjectedPlugin extends AutoPlugin {
override def trigger = allRequirements
override val projectSettings = Seq(
- scalaVersion := "0.1-SNAPSHOT",
+ scalaVersion := "0.1.1-SNAPSHOT",
scalaOrganization := "ch.epfl.lamp",
scalacOptions += "-language:Scala2",
scalaBinaryVersion := "2.11",
autoScalaLibrary := false,
libraryDependencies ++= Seq("org.scala-lang" % "scala-library" % "2.11.5"),
- scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % "0.1.1-SNAPSHOT" % "component").sources()
+ scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % scalaVersion.value % "component").sources()
)
}
diff --git a/sbt-bridge/sbt-test/discovery/test-discovery/build.sbt b/sbt-bridge/sbt-test/discovery/test-discovery/build.sbt
new file mode 100644
index 000000000..68b89ac35
--- /dev/null
+++ b/sbt-bridge/sbt-test/discovery/test-discovery/build.sbt
@@ -0,0 +1 @@
+libraryDependencies += "com.novocode" % "junit-interface" % "0.11" % "test"
diff --git a/sbt-bridge/sbt-test/discovery/test-discovery/changes/A2.scala b/sbt-bridge/sbt-test/discovery/test-discovery/changes/A2.scala
new file mode 100644
index 000000000..696daab5e
--- /dev/null
+++ b/sbt-bridge/sbt-test/discovery/test-discovery/changes/A2.scala
@@ -0,0 +1,3 @@
+object A {
+ def three: Int = 3 // Ah!
+}
diff --git a/sbt-bridge/sbt-test/discovery/test-discovery/project/DottyInjectedPlugin.scala b/sbt-bridge/sbt-test/discovery/test-discovery/project/DottyInjectedPlugin.scala
new file mode 100644
index 000000000..ecfbd69b3
--- /dev/null
+++ b/sbt-bridge/sbt-test/discovery/test-discovery/project/DottyInjectedPlugin.scala
@@ -0,0 +1,17 @@
+import sbt._
+import Keys._
+
+object DottyInjectedPlugin extends AutoPlugin {
+ override def requires = plugins.JvmPlugin
+ override def trigger = allRequirements
+
+ override val projectSettings = Seq(
+ scalaVersion := "0.1.1-SNAPSHOT",
+ scalaOrganization := "ch.epfl.lamp",
+ scalacOptions += "-language:Scala2",
+ scalaBinaryVersion := "2.11",
+ autoScalaLibrary := false,
+ libraryDependencies ++= Seq("org.scala-lang" % "scala-library" % "2.11.5"),
+ scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % scalaVersion.value % "component").sources()
+ )
+}
diff --git a/sbt-bridge/sbt-test/discovery/test-discovery/src/main/scala/A.scala b/sbt-bridge/sbt-test/discovery/test-discovery/src/main/scala/A.scala
new file mode 100644
index 000000000..81f77071e
--- /dev/null
+++ b/sbt-bridge/sbt-test/discovery/test-discovery/src/main/scala/A.scala
@@ -0,0 +1,3 @@
+object A {
+ def three: Int = 4 // Hmm
+}
diff --git a/sbt-bridge/sbt-test/discovery/test-discovery/src/test/scala/TestA.scala b/sbt-bridge/sbt-test/discovery/test-discovery/src/test/scala/TestA.scala
new file mode 100644
index 000000000..1d4f479d8
--- /dev/null
+++ b/sbt-bridge/sbt-test/discovery/test-discovery/src/test/scala/TestA.scala
@@ -0,0 +1,8 @@
+import org.junit.Test
+import org.junit.Assert.assertEquals
+
+class TestA {
+ @Test def testThree = {
+ assertEquals(A.three, 3)
+ }
+}
diff --git a/sbt-bridge/sbt-test/discovery/test-discovery/test b/sbt-bridge/sbt-test/discovery/test-discovery/test
new file mode 100644
index 000000000..2e035dee8
--- /dev/null
+++ b/sbt-bridge/sbt-test/discovery/test-discovery/test
@@ -0,0 +1,8 @@
+> compile
+# Intentionally failing test
+-> test
+# Fix the bug!
+$ copy-file changes/A2.scala src/main/scala/A.scala
+> compile
+# The test should pass now
+> test
diff --git a/sbt-bridge/sbt-test/source-dependencies/abstract-override/project/DottyInjectedPlugin.scala b/sbt-bridge/sbt-test/source-dependencies/abstract-override/project/DottyInjectedPlugin.scala
index ec22870f4..ecfbd69b3 100644
--- a/sbt-bridge/sbt-test/source-dependencies/abstract-override/project/DottyInjectedPlugin.scala
+++ b/sbt-bridge/sbt-test/source-dependencies/abstract-override/project/DottyInjectedPlugin.scala
@@ -6,12 +6,12 @@ object DottyInjectedPlugin extends AutoPlugin {
override def trigger = allRequirements
override val projectSettings = Seq(
- scalaVersion := "0.1-SNAPSHOT",
+ scalaVersion := "0.1.1-SNAPSHOT",
scalaOrganization := "ch.epfl.lamp",
scalacOptions += "-language:Scala2",
scalaBinaryVersion := "2.11",
autoScalaLibrary := false,
libraryDependencies ++= Seq("org.scala-lang" % "scala-library" % "2.11.5"),
- scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % "0.1.1-SNAPSHOT" % "component").sources()
+ scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % scalaVersion.value % "component").sources()
)
}
diff --git a/sbt-bridge/sbt-test/source-dependencies/abstract-type-override/project/DottyInjectedPlugin.scala b/sbt-bridge/sbt-test/source-dependencies/abstract-type-override/project/DottyInjectedPlugin.scala
index ec22870f4..ecfbd69b3 100644
--- a/sbt-bridge/sbt-test/source-dependencies/abstract-type-override/project/DottyInjectedPlugin.scala
+++ b/sbt-bridge/sbt-test/source-dependencies/abstract-type-override/project/DottyInjectedPlugin.scala
@@ -6,12 +6,12 @@ object DottyInjectedPlugin extends AutoPlugin {
override def trigger = allRequirements
override val projectSettings = Seq(
- scalaVersion := "0.1-SNAPSHOT",
+ scalaVersion := "0.1.1-SNAPSHOT",
scalaOrganization := "ch.epfl.lamp",
scalacOptions += "-language:Scala2",
scalaBinaryVersion := "2.11",
autoScalaLibrary := false,
libraryDependencies ++= Seq("org.scala-lang" % "scala-library" % "2.11.5"),
- scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % "0.1.1-SNAPSHOT" % "component").sources()
+ scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % scalaVersion.value % "component").sources()
)
}
diff --git a/sbt-bridge/sbt-test/source-dependencies/abstract-type/project/DottyInjectedPlugin.scala b/sbt-bridge/sbt-test/source-dependencies/abstract-type/project/DottyInjectedPlugin.scala
index ec22870f4..ecfbd69b3 100644
--- a/sbt-bridge/sbt-test/source-dependencies/abstract-type/project/DottyInjectedPlugin.scala
+++ b/sbt-bridge/sbt-test/source-dependencies/abstract-type/project/DottyInjectedPlugin.scala
@@ -6,12 +6,12 @@ object DottyInjectedPlugin extends AutoPlugin {
override def trigger = allRequirements
override val projectSettings = Seq(
- scalaVersion := "0.1-SNAPSHOT",
+ scalaVersion := "0.1.1-SNAPSHOT",
scalaOrganization := "ch.epfl.lamp",
scalacOptions += "-language:Scala2",
scalaBinaryVersion := "2.11",
autoScalaLibrary := false,
libraryDependencies ++= Seq("org.scala-lang" % "scala-library" % "2.11.5"),
- scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % "0.1.1-SNAPSHOT" % "component").sources()
+ scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % scalaVersion.value % "component").sources()
)
}
diff --git a/sbt-bridge/sbt-test/source-dependencies/added/project/DottyInjectedPlugin.scala b/sbt-bridge/sbt-test/source-dependencies/added/project/DottyInjectedPlugin.scala
index ec22870f4..ecfbd69b3 100644
--- a/sbt-bridge/sbt-test/source-dependencies/added/project/DottyInjectedPlugin.scala
+++ b/sbt-bridge/sbt-test/source-dependencies/added/project/DottyInjectedPlugin.scala
@@ -6,12 +6,12 @@ object DottyInjectedPlugin extends AutoPlugin {
override def trigger = allRequirements
override val projectSettings = Seq(
- scalaVersion := "0.1-SNAPSHOT",
+ scalaVersion := "0.1.1-SNAPSHOT",
scalaOrganization := "ch.epfl.lamp",
scalacOptions += "-language:Scala2",
scalaBinaryVersion := "2.11",
autoScalaLibrary := false,
libraryDependencies ++= Seq("org.scala-lang" % "scala-library" % "2.11.5"),
- scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % "0.1.1-SNAPSHOT" % "component").sources()
+ scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % scalaVersion.value % "component").sources()
)
}
diff --git a/sbt-bridge/sbt-test/source-dependencies/as-seen-from-a/project/DottyInjectedPlugin.scala b/sbt-bridge/sbt-test/source-dependencies/as-seen-from-a/project/DottyInjectedPlugin.scala
index ec22870f4..ecfbd69b3 100644
--- a/sbt-bridge/sbt-test/source-dependencies/as-seen-from-a/project/DottyInjectedPlugin.scala
+++ b/sbt-bridge/sbt-test/source-dependencies/as-seen-from-a/project/DottyInjectedPlugin.scala
@@ -6,12 +6,12 @@ object DottyInjectedPlugin extends AutoPlugin {
override def trigger = allRequirements
override val projectSettings = Seq(
- scalaVersion := "0.1-SNAPSHOT",
+ scalaVersion := "0.1.1-SNAPSHOT",
scalaOrganization := "ch.epfl.lamp",
scalacOptions += "-language:Scala2",
scalaBinaryVersion := "2.11",
autoScalaLibrary := false,
libraryDependencies ++= Seq("org.scala-lang" % "scala-library" % "2.11.5"),
- scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % "0.1.1-SNAPSHOT" % "component").sources()
+ scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % scalaVersion.value % "component").sources()
)
}
diff --git a/sbt-bridge/sbt-test/source-dependencies/as-seen-from-b/project/DottyInjectedPlugin.scala b/sbt-bridge/sbt-test/source-dependencies/as-seen-from-b/project/DottyInjectedPlugin.scala
index ec22870f4..ecfbd69b3 100644
--- a/sbt-bridge/sbt-test/source-dependencies/as-seen-from-b/project/DottyInjectedPlugin.scala
+++ b/sbt-bridge/sbt-test/source-dependencies/as-seen-from-b/project/DottyInjectedPlugin.scala
@@ -6,12 +6,12 @@ object DottyInjectedPlugin extends AutoPlugin {
override def trigger = allRequirements
override val projectSettings = Seq(
- scalaVersion := "0.1-SNAPSHOT",
+ scalaVersion := "0.1.1-SNAPSHOT",
scalaOrganization := "ch.epfl.lamp",
scalacOptions += "-language:Scala2",
scalaBinaryVersion := "2.11",
autoScalaLibrary := false,
libraryDependencies ++= Seq("org.scala-lang" % "scala-library" % "2.11.5"),
- scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % "0.1.1-SNAPSHOT" % "component").sources()
+ scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % scalaVersion.value % "component").sources()
)
}
diff --git a/sbt-bridge/sbt-test/source-dependencies/backtick-quoted-names/project/DottyInjectedPlugin.scala b/sbt-bridge/sbt-test/source-dependencies/backtick-quoted-names/project/DottyInjectedPlugin.scala
index ec22870f4..ecfbd69b3 100644
--- a/sbt-bridge/sbt-test/source-dependencies/backtick-quoted-names/project/DottyInjectedPlugin.scala
+++ b/sbt-bridge/sbt-test/source-dependencies/backtick-quoted-names/project/DottyInjectedPlugin.scala
@@ -6,12 +6,12 @@ object DottyInjectedPlugin extends AutoPlugin {
override def trigger = allRequirements
override val projectSettings = Seq(
- scalaVersion := "0.1-SNAPSHOT",
+ scalaVersion := "0.1.1-SNAPSHOT",
scalaOrganization := "ch.epfl.lamp",
scalacOptions += "-language:Scala2",
scalaBinaryVersion := "2.11",
autoScalaLibrary := false,
libraryDependencies ++= Seq("org.scala-lang" % "scala-library" % "2.11.5"),
- scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % "0.1.1-SNAPSHOT" % "component").sources()
+ scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % scalaVersion.value % "component").sources()
)
}
diff --git a/sbt-bridge/sbt-test/source-dependencies/binary/project/DottyInjectedPlugin.scala b/sbt-bridge/sbt-test/source-dependencies/binary/project/DottyInjectedPlugin.scala
index ec22870f4..ecfbd69b3 100644
--- a/sbt-bridge/sbt-test/source-dependencies/binary/project/DottyInjectedPlugin.scala
+++ b/sbt-bridge/sbt-test/source-dependencies/binary/project/DottyInjectedPlugin.scala
@@ -6,12 +6,12 @@ object DottyInjectedPlugin extends AutoPlugin {
override def trigger = allRequirements
override val projectSettings = Seq(
- scalaVersion := "0.1-SNAPSHOT",
+ scalaVersion := "0.1.1-SNAPSHOT",
scalaOrganization := "ch.epfl.lamp",
scalacOptions += "-language:Scala2",
scalaBinaryVersion := "2.11",
autoScalaLibrary := false,
libraryDependencies ++= Seq("org.scala-lang" % "scala-library" % "2.11.5"),
- scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % "0.1.1-SNAPSHOT" % "component").sources()
+ scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % scalaVersion.value % "component").sources()
)
}
diff --git a/sbt-bridge/sbt-test/source-dependencies/by-name/project/DottyInjectedPlugin.scala b/sbt-bridge/sbt-test/source-dependencies/by-name/project/DottyInjectedPlugin.scala
index ec22870f4..ecfbd69b3 100644
--- a/sbt-bridge/sbt-test/source-dependencies/by-name/project/DottyInjectedPlugin.scala
+++ b/sbt-bridge/sbt-test/source-dependencies/by-name/project/DottyInjectedPlugin.scala
@@ -6,12 +6,12 @@ object DottyInjectedPlugin extends AutoPlugin {
override def trigger = allRequirements
override val projectSettings = Seq(
- scalaVersion := "0.1-SNAPSHOT",
+ scalaVersion := "0.1.1-SNAPSHOT",
scalaOrganization := "ch.epfl.lamp",
scalacOptions += "-language:Scala2",
scalaBinaryVersion := "2.11",
autoScalaLibrary := false,
libraryDependencies ++= Seq("org.scala-lang" % "scala-library" % "2.11.5"),
- scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % "0.1.1-SNAPSHOT" % "component").sources()
+ scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % scalaVersion.value % "component").sources()
)
}
diff --git a/sbt-bridge/sbt-test/source-dependencies/canon/project/DottyInjectedPlugin.scala b/sbt-bridge/sbt-test/source-dependencies/canon/project/DottyInjectedPlugin.scala
index ec22870f4..ecfbd69b3 100644
--- a/sbt-bridge/sbt-test/source-dependencies/canon/project/DottyInjectedPlugin.scala
+++ b/sbt-bridge/sbt-test/source-dependencies/canon/project/DottyInjectedPlugin.scala
@@ -6,12 +6,12 @@ object DottyInjectedPlugin extends AutoPlugin {
override def trigger = allRequirements
override val projectSettings = Seq(
- scalaVersion := "0.1-SNAPSHOT",
+ scalaVersion := "0.1.1-SNAPSHOT",
scalaOrganization := "ch.epfl.lamp",
scalacOptions += "-language:Scala2",
scalaBinaryVersion := "2.11",
autoScalaLibrary := false,
libraryDependencies ++= Seq("org.scala-lang" % "scala-library" % "2.11.5"),
- scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % "0.1.1-SNAPSHOT" % "component").sources()
+ scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % scalaVersion.value % "component").sources()
)
}
diff --git a/sbt-bridge/sbt-test/source-dependencies/compactify/project/DottyInjectedPlugin.scala b/sbt-bridge/sbt-test/source-dependencies/compactify/project/DottyInjectedPlugin.scala
index ec22870f4..ecfbd69b3 100644
--- a/sbt-bridge/sbt-test/source-dependencies/compactify/project/DottyInjectedPlugin.scala
+++ b/sbt-bridge/sbt-test/source-dependencies/compactify/project/DottyInjectedPlugin.scala
@@ -6,12 +6,12 @@ object DottyInjectedPlugin extends AutoPlugin {
override def trigger = allRequirements
override val projectSettings = Seq(
- scalaVersion := "0.1-SNAPSHOT",
+ scalaVersion := "0.1.1-SNAPSHOT",
scalaOrganization := "ch.epfl.lamp",
scalacOptions += "-language:Scala2",
scalaBinaryVersion := "2.11",
autoScalaLibrary := false,
libraryDependencies ++= Seq("org.scala-lang" % "scala-library" % "2.11.5"),
- scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % "0.1.1-SNAPSHOT" % "component").sources()
+ scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % scalaVersion.value % "component").sources()
)
}
diff --git a/sbt-bridge/sbt-test/source-dependencies/constants/project/DottyInjectedPlugin.scala b/sbt-bridge/sbt-test/source-dependencies/constants/project/DottyInjectedPlugin.scala
index ec22870f4..ecfbd69b3 100644
--- a/sbt-bridge/sbt-test/source-dependencies/constants/project/DottyInjectedPlugin.scala
+++ b/sbt-bridge/sbt-test/source-dependencies/constants/project/DottyInjectedPlugin.scala
@@ -6,12 +6,12 @@ object DottyInjectedPlugin extends AutoPlugin {
override def trigger = allRequirements
override val projectSettings = Seq(
- scalaVersion := "0.1-SNAPSHOT",
+ scalaVersion := "0.1.1-SNAPSHOT",
scalaOrganization := "ch.epfl.lamp",
scalacOptions += "-language:Scala2",
scalaBinaryVersion := "2.11",
autoScalaLibrary := false,
libraryDependencies ++= Seq("org.scala-lang" % "scala-library" % "2.11.5"),
- scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % "0.1.1-SNAPSHOT" % "component").sources()
+ scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % scalaVersion.value % "component").sources()
)
}
diff --git a/sbt-bridge/sbt-test/source-dependencies/default-params/project/DottyInjectedPlugin.scala b/sbt-bridge/sbt-test/source-dependencies/default-params/project/DottyInjectedPlugin.scala
index ec22870f4..ecfbd69b3 100644
--- a/sbt-bridge/sbt-test/source-dependencies/default-params/project/DottyInjectedPlugin.scala
+++ b/sbt-bridge/sbt-test/source-dependencies/default-params/project/DottyInjectedPlugin.scala
@@ -6,12 +6,12 @@ object DottyInjectedPlugin extends AutoPlugin {
override def trigger = allRequirements
override val projectSettings = Seq(
- scalaVersion := "0.1-SNAPSHOT",
+ scalaVersion := "0.1.1-SNAPSHOT",
scalaOrganization := "ch.epfl.lamp",
scalacOptions += "-language:Scala2",
scalaBinaryVersion := "2.11",
autoScalaLibrary := false,
libraryDependencies ++= Seq("org.scala-lang" % "scala-library" % "2.11.5"),
- scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % "0.1.1-SNAPSHOT" % "component").sources()
+ scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % scalaVersion.value % "component").sources()
)
}
diff --git a/sbt-bridge/sbt-test/source-dependencies/dup-class/project/DottyInjectedPlugin.scala b/sbt-bridge/sbt-test/source-dependencies/dup-class/project/DottyInjectedPlugin.scala
index ec22870f4..ecfbd69b3 100644
--- a/sbt-bridge/sbt-test/source-dependencies/dup-class/project/DottyInjectedPlugin.scala
+++ b/sbt-bridge/sbt-test/source-dependencies/dup-class/project/DottyInjectedPlugin.scala
@@ -6,12 +6,12 @@ object DottyInjectedPlugin extends AutoPlugin {
override def trigger = allRequirements
override val projectSettings = Seq(
- scalaVersion := "0.1-SNAPSHOT",
+ scalaVersion := "0.1.1-SNAPSHOT",
scalaOrganization := "ch.epfl.lamp",
scalacOptions += "-language:Scala2",
scalaBinaryVersion := "2.11",
autoScalaLibrary := false,
libraryDependencies ++= Seq("org.scala-lang" % "scala-library" % "2.11.5"),
- scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % "0.1.1-SNAPSHOT" % "component").sources()
+ scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % scalaVersion.value % "component").sources()
)
}
diff --git a/sbt-bridge/sbt-test/source-dependencies/empty-a/project/DottyInjectedPlugin.scala b/sbt-bridge/sbt-test/source-dependencies/empty-a/project/DottyInjectedPlugin.scala
index ec22870f4..ecfbd69b3 100644
--- a/sbt-bridge/sbt-test/source-dependencies/empty-a/project/DottyInjectedPlugin.scala
+++ b/sbt-bridge/sbt-test/source-dependencies/empty-a/project/DottyInjectedPlugin.scala
@@ -6,12 +6,12 @@ object DottyInjectedPlugin extends AutoPlugin {
override def trigger = allRequirements
override val projectSettings = Seq(
- scalaVersion := "0.1-SNAPSHOT",
+ scalaVersion := "0.1.1-SNAPSHOT",
scalaOrganization := "ch.epfl.lamp",
scalacOptions += "-language:Scala2",
scalaBinaryVersion := "2.11",
autoScalaLibrary := false,
libraryDependencies ++= Seq("org.scala-lang" % "scala-library" % "2.11.5"),
- scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % "0.1.1-SNAPSHOT" % "component").sources()
+ scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % scalaVersion.value % "component").sources()
)
}
diff --git a/sbt-bridge/sbt-test/source-dependencies/empty-package/project/DottyInjectedPlugin.scala b/sbt-bridge/sbt-test/source-dependencies/empty-package/project/DottyInjectedPlugin.scala
index ec22870f4..ecfbd69b3 100644
--- a/sbt-bridge/sbt-test/source-dependencies/empty-package/project/DottyInjectedPlugin.scala
+++ b/sbt-bridge/sbt-test/source-dependencies/empty-package/project/DottyInjectedPlugin.scala
@@ -6,12 +6,12 @@ object DottyInjectedPlugin extends AutoPlugin {
override def trigger = allRequirements
override val projectSettings = Seq(
- scalaVersion := "0.1-SNAPSHOT",
+ scalaVersion := "0.1.1-SNAPSHOT",
scalaOrganization := "ch.epfl.lamp",
scalacOptions += "-language:Scala2",
scalaBinaryVersion := "2.11",
autoScalaLibrary := false,
libraryDependencies ++= Seq("org.scala-lang" % "scala-library" % "2.11.5"),
- scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % "0.1.1-SNAPSHOT" % "component").sources()
+ scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % scalaVersion.value % "component").sources()
)
}
diff --git a/sbt-bridge/sbt-test/source-dependencies/erasure/project/DottyInjectedPlugin.scala b/sbt-bridge/sbt-test/source-dependencies/erasure/project/DottyInjectedPlugin.scala
index ec22870f4..ecfbd69b3 100644
--- a/sbt-bridge/sbt-test/source-dependencies/erasure/project/DottyInjectedPlugin.scala
+++ b/sbt-bridge/sbt-test/source-dependencies/erasure/project/DottyInjectedPlugin.scala
@@ -6,12 +6,12 @@ object DottyInjectedPlugin extends AutoPlugin {
override def trigger = allRequirements
override val projectSettings = Seq(
- scalaVersion := "0.1-SNAPSHOT",
+ scalaVersion := "0.1.1-SNAPSHOT",
scalaOrganization := "ch.epfl.lamp",
scalacOptions += "-language:Scala2",
scalaBinaryVersion := "2.11",
autoScalaLibrary := false,
libraryDependencies ++= Seq("org.scala-lang" % "scala-library" % "2.11.5"),
- scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % "0.1.1-SNAPSHOT" % "component").sources()
+ scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % scalaVersion.value % "component").sources()
)
}
diff --git a/sbt-bridge/sbt-test/source-dependencies/export-jars/project/DottyInjectedPlugin.scala b/sbt-bridge/sbt-test/source-dependencies/export-jars/project/DottyInjectedPlugin.scala
index ec22870f4..ecfbd69b3 100644
--- a/sbt-bridge/sbt-test/source-dependencies/export-jars/project/DottyInjectedPlugin.scala
+++ b/sbt-bridge/sbt-test/source-dependencies/export-jars/project/DottyInjectedPlugin.scala
@@ -6,12 +6,12 @@ object DottyInjectedPlugin extends AutoPlugin {
override def trigger = allRequirements
override val projectSettings = Seq(
- scalaVersion := "0.1-SNAPSHOT",
+ scalaVersion := "0.1.1-SNAPSHOT",
scalaOrganization := "ch.epfl.lamp",
scalacOptions += "-language:Scala2",
scalaBinaryVersion := "2.11",
autoScalaLibrary := false,
libraryDependencies ++= Seq("org.scala-lang" % "scala-library" % "2.11.5"),
- scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % "0.1.1-SNAPSHOT" % "component").sources()
+ scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % scalaVersion.value % "component").sources()
)
}
diff --git a/sbt-bridge/sbt-test/source-dependencies/ext/project/DottyInjectedPlugin.scala b/sbt-bridge/sbt-test/source-dependencies/ext/project/DottyInjectedPlugin.scala
index ec22870f4..ecfbd69b3 100644
--- a/sbt-bridge/sbt-test/source-dependencies/ext/project/DottyInjectedPlugin.scala
+++ b/sbt-bridge/sbt-test/source-dependencies/ext/project/DottyInjectedPlugin.scala
@@ -6,12 +6,12 @@ object DottyInjectedPlugin extends AutoPlugin {
override def trigger = allRequirements
override val projectSettings = Seq(
- scalaVersion := "0.1-SNAPSHOT",
+ scalaVersion := "0.1.1-SNAPSHOT",
scalaOrganization := "ch.epfl.lamp",
scalacOptions += "-language:Scala2",
scalaBinaryVersion := "2.11",
autoScalaLibrary := false,
libraryDependencies ++= Seq("org.scala-lang" % "scala-library" % "2.11.5"),
- scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % "0.1.1-SNAPSHOT" % "component").sources()
+ scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % scalaVersion.value % "component").sources()
)
}
diff --git a/sbt-bridge/sbt-test/source-dependencies/false-error/project/DottyInjectedPlugin.scala b/sbt-bridge/sbt-test/source-dependencies/false-error/project/DottyInjectedPlugin.scala
index ec22870f4..ecfbd69b3 100644
--- a/sbt-bridge/sbt-test/source-dependencies/false-error/project/DottyInjectedPlugin.scala
+++ b/sbt-bridge/sbt-test/source-dependencies/false-error/project/DottyInjectedPlugin.scala
@@ -6,12 +6,12 @@ object DottyInjectedPlugin extends AutoPlugin {
override def trigger = allRequirements
override val projectSettings = Seq(
- scalaVersion := "0.1-SNAPSHOT",
+ scalaVersion := "0.1.1-SNAPSHOT",
scalaOrganization := "ch.epfl.lamp",
scalacOptions += "-language:Scala2",
scalaBinaryVersion := "2.11",
autoScalaLibrary := false,
libraryDependencies ++= Seq("org.scala-lang" % "scala-library" % "2.11.5"),
- scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % "0.1.1-SNAPSHOT" % "component").sources()
+ scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % scalaVersion.value % "component").sources()
)
}
diff --git a/sbt-bridge/sbt-test/source-dependencies/fbounded-existentials/project/DottyInjectedPlugin.scala b/sbt-bridge/sbt-test/source-dependencies/fbounded-existentials/project/DottyInjectedPlugin.scala
index ec22870f4..ecfbd69b3 100644
--- a/sbt-bridge/sbt-test/source-dependencies/fbounded-existentials/project/DottyInjectedPlugin.scala
+++ b/sbt-bridge/sbt-test/source-dependencies/fbounded-existentials/project/DottyInjectedPlugin.scala
@@ -6,12 +6,12 @@ object DottyInjectedPlugin extends AutoPlugin {
override def trigger = allRequirements
override val projectSettings = Seq(
- scalaVersion := "0.1-SNAPSHOT",
+ scalaVersion := "0.1.1-SNAPSHOT",
scalaOrganization := "ch.epfl.lamp",
scalacOptions += "-language:Scala2",
scalaBinaryVersion := "2.11",
autoScalaLibrary := false,
libraryDependencies ++= Seq("org.scala-lang" % "scala-library" % "2.11.5"),
- scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % "0.1.1-SNAPSHOT" % "component").sources()
+ scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % scalaVersion.value % "component").sources()
)
}
diff --git a/sbt-bridge/sbt-test/source-dependencies/implicit-params/project/DottyInjectedPlugin.scala b/sbt-bridge/sbt-test/source-dependencies/implicit-params/project/DottyInjectedPlugin.scala
index ec22870f4..ecfbd69b3 100644
--- a/sbt-bridge/sbt-test/source-dependencies/implicit-params/project/DottyInjectedPlugin.scala
+++ b/sbt-bridge/sbt-test/source-dependencies/implicit-params/project/DottyInjectedPlugin.scala
@@ -6,12 +6,12 @@ object DottyInjectedPlugin extends AutoPlugin {
override def trigger = allRequirements
override val projectSettings = Seq(
- scalaVersion := "0.1-SNAPSHOT",
+ scalaVersion := "0.1.1-SNAPSHOT",
scalaOrganization := "ch.epfl.lamp",
scalacOptions += "-language:Scala2",
scalaBinaryVersion := "2.11",
autoScalaLibrary := false,
libraryDependencies ++= Seq("org.scala-lang" % "scala-library" % "2.11.5"),
- scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % "0.1.1-SNAPSHOT" % "component").sources()
+ scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % scalaVersion.value % "component").sources()
)
}
diff --git a/sbt-bridge/sbt-test/source-dependencies/implicit-search-companion-scope/project/DottyInjectedPlugin.scala b/sbt-bridge/sbt-test/source-dependencies/implicit-search-companion-scope/project/DottyInjectedPlugin.scala
index ec22870f4..ecfbd69b3 100644
--- a/sbt-bridge/sbt-test/source-dependencies/implicit-search-companion-scope/project/DottyInjectedPlugin.scala
+++ b/sbt-bridge/sbt-test/source-dependencies/implicit-search-companion-scope/project/DottyInjectedPlugin.scala
@@ -6,12 +6,12 @@ object DottyInjectedPlugin extends AutoPlugin {
override def trigger = allRequirements
override val projectSettings = Seq(
- scalaVersion := "0.1-SNAPSHOT",
+ scalaVersion := "0.1.1-SNAPSHOT",
scalaOrganization := "ch.epfl.lamp",
scalacOptions += "-language:Scala2",
scalaBinaryVersion := "2.11",
autoScalaLibrary := false,
libraryDependencies ++= Seq("org.scala-lang" % "scala-library" % "2.11.5"),
- scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % "0.1.1-SNAPSHOT" % "component").sources()
+ scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % scalaVersion.value % "component").sources()
)
}
diff --git a/sbt-bridge/sbt-test/source-dependencies/implicit-search/project/DottyInjectedPlugin.scala b/sbt-bridge/sbt-test/source-dependencies/implicit-search/project/DottyInjectedPlugin.scala
index ec22870f4..ecfbd69b3 100644
--- a/sbt-bridge/sbt-test/source-dependencies/implicit-search/project/DottyInjectedPlugin.scala
+++ b/sbt-bridge/sbt-test/source-dependencies/implicit-search/project/DottyInjectedPlugin.scala
@@ -6,12 +6,12 @@ object DottyInjectedPlugin extends AutoPlugin {
override def trigger = allRequirements
override val projectSettings = Seq(
- scalaVersion := "0.1-SNAPSHOT",
+ scalaVersion := "0.1.1-SNAPSHOT",
scalaOrganization := "ch.epfl.lamp",
scalacOptions += "-language:Scala2",
scalaBinaryVersion := "2.11",
autoScalaLibrary := false,
libraryDependencies ++= Seq("org.scala-lang" % "scala-library" % "2.11.5"),
- scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % "0.1.1-SNAPSHOT" % "component").sources()
+ scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % scalaVersion.value % "component").sources()
)
}
diff --git a/sbt-bridge/sbt-test/source-dependencies/implicit/project/DottyInjectedPlugin.scala b/sbt-bridge/sbt-test/source-dependencies/implicit/project/DottyInjectedPlugin.scala
index ec22870f4..ecfbd69b3 100644
--- a/sbt-bridge/sbt-test/source-dependencies/implicit/project/DottyInjectedPlugin.scala
+++ b/sbt-bridge/sbt-test/source-dependencies/implicit/project/DottyInjectedPlugin.scala
@@ -6,12 +6,12 @@ object DottyInjectedPlugin extends AutoPlugin {
override def trigger = allRequirements
override val projectSettings = Seq(
- scalaVersion := "0.1-SNAPSHOT",
+ scalaVersion := "0.1.1-SNAPSHOT",
scalaOrganization := "ch.epfl.lamp",
scalacOptions += "-language:Scala2",
scalaBinaryVersion := "2.11",
autoScalaLibrary := false,
libraryDependencies ++= Seq("org.scala-lang" % "scala-library" % "2.11.5"),
- scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % "0.1.1-SNAPSHOT" % "component").sources()
+ scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % scalaVersion.value % "component").sources()
)
}
diff --git a/sbt-bridge/sbt-test/source-dependencies/import-class/project/DottyInjectedPlugin.scala b/sbt-bridge/sbt-test/source-dependencies/import-class/project/DottyInjectedPlugin.scala
index ec22870f4..ecfbd69b3 100644
--- a/sbt-bridge/sbt-test/source-dependencies/import-class/project/DottyInjectedPlugin.scala
+++ b/sbt-bridge/sbt-test/source-dependencies/import-class/project/DottyInjectedPlugin.scala
@@ -6,12 +6,12 @@ object DottyInjectedPlugin extends AutoPlugin {
override def trigger = allRequirements
override val projectSettings = Seq(
- scalaVersion := "0.1-SNAPSHOT",
+ scalaVersion := "0.1.1-SNAPSHOT",
scalaOrganization := "ch.epfl.lamp",
scalacOptions += "-language:Scala2",
scalaBinaryVersion := "2.11",
autoScalaLibrary := false,
libraryDependencies ++= Seq("org.scala-lang" % "scala-library" % "2.11.5"),
- scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % "0.1.1-SNAPSHOT" % "component").sources()
+ scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % scalaVersion.value % "component").sources()
)
}
diff --git a/sbt-bridge/sbt-test/source-dependencies/import-package/project/DottyInjectedPlugin.scala b/sbt-bridge/sbt-test/source-dependencies/import-package/project/DottyInjectedPlugin.scala
index ec22870f4..ecfbd69b3 100644
--- a/sbt-bridge/sbt-test/source-dependencies/import-package/project/DottyInjectedPlugin.scala
+++ b/sbt-bridge/sbt-test/source-dependencies/import-package/project/DottyInjectedPlugin.scala
@@ -6,12 +6,12 @@ object DottyInjectedPlugin extends AutoPlugin {
override def trigger = allRequirements
override val projectSettings = Seq(
- scalaVersion := "0.1-SNAPSHOT",
+ scalaVersion := "0.1.1-SNAPSHOT",
scalaOrganization := "ch.epfl.lamp",
scalacOptions += "-language:Scala2",
scalaBinaryVersion := "2.11",
autoScalaLibrary := false,
libraryDependencies ++= Seq("org.scala-lang" % "scala-library" % "2.11.5"),
- scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % "0.1.1-SNAPSHOT" % "component").sources()
+ scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % scalaVersion.value % "component").sources()
)
}
diff --git a/sbt-bridge/sbt-test/source-dependencies/inherited-deps-java/project/DottyInjectedPlugin.scala b/sbt-bridge/sbt-test/source-dependencies/inherited-deps-java/project/DottyInjectedPlugin.scala
index ec22870f4..ecfbd69b3 100644
--- a/sbt-bridge/sbt-test/source-dependencies/inherited-deps-java/project/DottyInjectedPlugin.scala
+++ b/sbt-bridge/sbt-test/source-dependencies/inherited-deps-java/project/DottyInjectedPlugin.scala
@@ -6,12 +6,12 @@ object DottyInjectedPlugin extends AutoPlugin {
override def trigger = allRequirements
override val projectSettings = Seq(
- scalaVersion := "0.1-SNAPSHOT",
+ scalaVersion := "0.1.1-SNAPSHOT",
scalaOrganization := "ch.epfl.lamp",
scalacOptions += "-language:Scala2",
scalaBinaryVersion := "2.11",
autoScalaLibrary := false,
libraryDependencies ++= Seq("org.scala-lang" % "scala-library" % "2.11.5"),
- scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % "0.1.1-SNAPSHOT" % "component").sources()
+ scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % scalaVersion.value % "component").sources()
)
}
diff --git a/sbt-bridge/sbt-test/source-dependencies/inherited_type_params/project/DottyInjectedPlugin.scala b/sbt-bridge/sbt-test/source-dependencies/inherited_type_params/project/DottyInjectedPlugin.scala
index ec22870f4..ecfbd69b3 100644
--- a/sbt-bridge/sbt-test/source-dependencies/inherited_type_params/project/DottyInjectedPlugin.scala
+++ b/sbt-bridge/sbt-test/source-dependencies/inherited_type_params/project/DottyInjectedPlugin.scala
@@ -6,12 +6,12 @@ object DottyInjectedPlugin extends AutoPlugin {
override def trigger = allRequirements
override val projectSettings = Seq(
- scalaVersion := "0.1-SNAPSHOT",
+ scalaVersion := "0.1.1-SNAPSHOT",
scalaOrganization := "ch.epfl.lamp",
scalacOptions += "-language:Scala2",
scalaBinaryVersion := "2.11",
autoScalaLibrary := false,
libraryDependencies ++= Seq("org.scala-lang" % "scala-library" % "2.11.5"),
- scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % "0.1.1-SNAPSHOT" % "component").sources()
+ scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % scalaVersion.value % "component").sources()
)
}
diff --git a/sbt-bridge/sbt-test/source-dependencies/inline/project/DottyInjectedPlugin.scala b/sbt-bridge/sbt-test/source-dependencies/inline/project/DottyInjectedPlugin.scala
index ec22870f4..ecfbd69b3 100644
--- a/sbt-bridge/sbt-test/source-dependencies/inline/project/DottyInjectedPlugin.scala
+++ b/sbt-bridge/sbt-test/source-dependencies/inline/project/DottyInjectedPlugin.scala
@@ -6,12 +6,12 @@ object DottyInjectedPlugin extends AutoPlugin {
override def trigger = allRequirements
override val projectSettings = Seq(
- scalaVersion := "0.1-SNAPSHOT",
+ scalaVersion := "0.1.1-SNAPSHOT",
scalaOrganization := "ch.epfl.lamp",
scalacOptions += "-language:Scala2",
scalaBinaryVersion := "2.11",
autoScalaLibrary := false,
libraryDependencies ++= Seq("org.scala-lang" % "scala-library" % "2.11.5"),
- scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % "0.1.1-SNAPSHOT" % "component").sources()
+ scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % scalaVersion.value % "component").sources()
)
}
diff --git a/sbt-bridge/sbt-test/source-dependencies/intermediate-error/project/DottyInjectedPlugin.scala b/sbt-bridge/sbt-test/source-dependencies/intermediate-error/project/DottyInjectedPlugin.scala
index ec22870f4..ecfbd69b3 100644
--- a/sbt-bridge/sbt-test/source-dependencies/intermediate-error/project/DottyInjectedPlugin.scala
+++ b/sbt-bridge/sbt-test/source-dependencies/intermediate-error/project/DottyInjectedPlugin.scala
@@ -6,12 +6,12 @@ object DottyInjectedPlugin extends AutoPlugin {
override def trigger = allRequirements
override val projectSettings = Seq(
- scalaVersion := "0.1-SNAPSHOT",
+ scalaVersion := "0.1.1-SNAPSHOT",
scalaOrganization := "ch.epfl.lamp",
scalacOptions += "-language:Scala2",
scalaBinaryVersion := "2.11",
autoScalaLibrary := false,
libraryDependencies ++= Seq("org.scala-lang" % "scala-library" % "2.11.5"),
- scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % "0.1.1-SNAPSHOT" % "component").sources()
+ scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % scalaVersion.value % "component").sources()
)
}
diff --git a/sbt-bridge/sbt-test/source-dependencies/java-analysis-serialization-error/project/DottyInjectedPlugin.scala b/sbt-bridge/sbt-test/source-dependencies/java-analysis-serialization-error/project/DottyInjectedPlugin.scala
index ec22870f4..ecfbd69b3 100644
--- a/sbt-bridge/sbt-test/source-dependencies/java-analysis-serialization-error/project/DottyInjectedPlugin.scala
+++ b/sbt-bridge/sbt-test/source-dependencies/java-analysis-serialization-error/project/DottyInjectedPlugin.scala
@@ -6,12 +6,12 @@ object DottyInjectedPlugin extends AutoPlugin {
override def trigger = allRequirements
override val projectSettings = Seq(
- scalaVersion := "0.1-SNAPSHOT",
+ scalaVersion := "0.1.1-SNAPSHOT",
scalaOrganization := "ch.epfl.lamp",
scalacOptions += "-language:Scala2",
scalaBinaryVersion := "2.11",
autoScalaLibrary := false,
libraryDependencies ++= Seq("org.scala-lang" % "scala-library" % "2.11.5"),
- scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % "0.1.1-SNAPSHOT" % "component").sources()
+ scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % scalaVersion.value % "component").sources()
)
}
diff --git a/sbt-bridge/sbt-test/source-dependencies/java-basic/project/DottyInjectedPlugin.scala b/sbt-bridge/sbt-test/source-dependencies/java-basic/project/DottyInjectedPlugin.scala
index ec22870f4..ecfbd69b3 100644
--- a/sbt-bridge/sbt-test/source-dependencies/java-basic/project/DottyInjectedPlugin.scala
+++ b/sbt-bridge/sbt-test/source-dependencies/java-basic/project/DottyInjectedPlugin.scala
@@ -6,12 +6,12 @@ object DottyInjectedPlugin extends AutoPlugin {
override def trigger = allRequirements
override val projectSettings = Seq(
- scalaVersion := "0.1-SNAPSHOT",
+ scalaVersion := "0.1.1-SNAPSHOT",
scalaOrganization := "ch.epfl.lamp",
scalacOptions += "-language:Scala2",
scalaBinaryVersion := "2.11",
autoScalaLibrary := false,
libraryDependencies ++= Seq("org.scala-lang" % "scala-library" % "2.11.5"),
- scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % "0.1.1-SNAPSHOT" % "component").sources()
+ scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % scalaVersion.value % "component").sources()
)
}
diff --git a/sbt-bridge/sbt-test/source-dependencies/java-generic-workaround/project/DottyInjectedPlugin.scala b/sbt-bridge/sbt-test/source-dependencies/java-generic-workaround/project/DottyInjectedPlugin.scala
index ec22870f4..ecfbd69b3 100644
--- a/sbt-bridge/sbt-test/source-dependencies/java-generic-workaround/project/DottyInjectedPlugin.scala
+++ b/sbt-bridge/sbt-test/source-dependencies/java-generic-workaround/project/DottyInjectedPlugin.scala
@@ -6,12 +6,12 @@ object DottyInjectedPlugin extends AutoPlugin {
override def trigger = allRequirements
override val projectSettings = Seq(
- scalaVersion := "0.1-SNAPSHOT",
+ scalaVersion := "0.1.1-SNAPSHOT",
scalaOrganization := "ch.epfl.lamp",
scalacOptions += "-language:Scala2",
scalaBinaryVersion := "2.11",
autoScalaLibrary := false,
libraryDependencies ++= Seq("org.scala-lang" % "scala-library" % "2.11.5"),
- scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % "0.1.1-SNAPSHOT" % "component").sources()
+ scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % scalaVersion.value % "component").sources()
)
}
diff --git a/sbt-bridge/sbt-test/source-dependencies/java-mixed/project/DottyInjectedPlugin.scala b/sbt-bridge/sbt-test/source-dependencies/java-mixed/project/DottyInjectedPlugin.scala
index ec22870f4..ecfbd69b3 100644
--- a/sbt-bridge/sbt-test/source-dependencies/java-mixed/project/DottyInjectedPlugin.scala
+++ b/sbt-bridge/sbt-test/source-dependencies/java-mixed/project/DottyInjectedPlugin.scala
@@ -6,12 +6,12 @@ object DottyInjectedPlugin extends AutoPlugin {
override def trigger = allRequirements
override val projectSettings = Seq(
- scalaVersion := "0.1-SNAPSHOT",
+ scalaVersion := "0.1.1-SNAPSHOT",
scalaOrganization := "ch.epfl.lamp",
scalacOptions += "-language:Scala2",
scalaBinaryVersion := "2.11",
autoScalaLibrary := false,
libraryDependencies ++= Seq("org.scala-lang" % "scala-library" % "2.11.5"),
- scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % "0.1.1-SNAPSHOT" % "component").sources()
+ scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % scalaVersion.value % "component").sources()
)
}
diff --git a/sbt-bridge/sbt-test/source-dependencies/java-static/project/DottyInjectedPlugin.scala b/sbt-bridge/sbt-test/source-dependencies/java-static/project/DottyInjectedPlugin.scala
index ec22870f4..ecfbd69b3 100644
--- a/sbt-bridge/sbt-test/source-dependencies/java-static/project/DottyInjectedPlugin.scala
+++ b/sbt-bridge/sbt-test/source-dependencies/java-static/project/DottyInjectedPlugin.scala
@@ -6,12 +6,12 @@ object DottyInjectedPlugin extends AutoPlugin {
override def trigger = allRequirements
override val projectSettings = Seq(
- scalaVersion := "0.1-SNAPSHOT",
+ scalaVersion := "0.1.1-SNAPSHOT",
scalaOrganization := "ch.epfl.lamp",
scalacOptions += "-language:Scala2",
scalaBinaryVersion := "2.11",
autoScalaLibrary := false,
libraryDependencies ++= Seq("org.scala-lang" % "scala-library" % "2.11.5"),
- scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % "0.1.1-SNAPSHOT" % "component").sources()
+ scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % scalaVersion.value % "component").sources()
)
}
diff --git a/sbt-bridge/sbt-test/source-dependencies/lazy-val/project/DottyInjectedPlugin.scala b/sbt-bridge/sbt-test/source-dependencies/lazy-val/project/DottyInjectedPlugin.scala
index ec22870f4..ecfbd69b3 100644
--- a/sbt-bridge/sbt-test/source-dependencies/lazy-val/project/DottyInjectedPlugin.scala
+++ b/sbt-bridge/sbt-test/source-dependencies/lazy-val/project/DottyInjectedPlugin.scala
@@ -6,12 +6,12 @@ object DottyInjectedPlugin extends AutoPlugin {
override def trigger = allRequirements
override val projectSettings = Seq(
- scalaVersion := "0.1-SNAPSHOT",
+ scalaVersion := "0.1.1-SNAPSHOT",
scalaOrganization := "ch.epfl.lamp",
scalacOptions += "-language:Scala2",
scalaBinaryVersion := "2.11",
autoScalaLibrary := false,
libraryDependencies ++= Seq("org.scala-lang" % "scala-library" % "2.11.5"),
- scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % "0.1.1-SNAPSHOT" % "component").sources()
+ scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % scalaVersion.value % "component").sources()
)
}
diff --git a/sbt-bridge/sbt-test/source-dependencies/less-inter-inv-java/project/DottyInjectedPlugin.scala b/sbt-bridge/sbt-test/source-dependencies/less-inter-inv-java/project/DottyInjectedPlugin.scala
index ec22870f4..ecfbd69b3 100644
--- a/sbt-bridge/sbt-test/source-dependencies/less-inter-inv-java/project/DottyInjectedPlugin.scala
+++ b/sbt-bridge/sbt-test/source-dependencies/less-inter-inv-java/project/DottyInjectedPlugin.scala
@@ -6,12 +6,12 @@ object DottyInjectedPlugin extends AutoPlugin {
override def trigger = allRequirements
override val projectSettings = Seq(
- scalaVersion := "0.1-SNAPSHOT",
+ scalaVersion := "0.1.1-SNAPSHOT",
scalaOrganization := "ch.epfl.lamp",
scalacOptions += "-language:Scala2",
scalaBinaryVersion := "2.11",
autoScalaLibrary := false,
libraryDependencies ++= Seq("org.scala-lang" % "scala-library" % "2.11.5"),
- scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % "0.1.1-SNAPSHOT" % "component").sources()
+ scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % scalaVersion.value % "component").sources()
)
}
diff --git a/sbt-bridge/sbt-test/source-dependencies/less-inter-inv/project/DottyInjectedPlugin.scala b/sbt-bridge/sbt-test/source-dependencies/less-inter-inv/project/DottyInjectedPlugin.scala
index ec22870f4..ecfbd69b3 100644
--- a/sbt-bridge/sbt-test/source-dependencies/less-inter-inv/project/DottyInjectedPlugin.scala
+++ b/sbt-bridge/sbt-test/source-dependencies/less-inter-inv/project/DottyInjectedPlugin.scala
@@ -6,12 +6,12 @@ object DottyInjectedPlugin extends AutoPlugin {
override def trigger = allRequirements
override val projectSettings = Seq(
- scalaVersion := "0.1-SNAPSHOT",
+ scalaVersion := "0.1.1-SNAPSHOT",
scalaOrganization := "ch.epfl.lamp",
scalacOptions += "-language:Scala2",
scalaBinaryVersion := "2.11",
autoScalaLibrary := false,
libraryDependencies ++= Seq("org.scala-lang" % "scala-library" % "2.11.5"),
- scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % "0.1.1-SNAPSHOT" % "component").sources()
+ scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % scalaVersion.value % "component").sources()
)
}
diff --git a/sbt-bridge/sbt-test/source-dependencies/linearization/project/DottyInjectedPlugin.scala b/sbt-bridge/sbt-test/source-dependencies/linearization/project/DottyInjectedPlugin.scala
index ec22870f4..ecfbd69b3 100644
--- a/sbt-bridge/sbt-test/source-dependencies/linearization/project/DottyInjectedPlugin.scala
+++ b/sbt-bridge/sbt-test/source-dependencies/linearization/project/DottyInjectedPlugin.scala
@@ -6,12 +6,12 @@ object DottyInjectedPlugin extends AutoPlugin {
override def trigger = allRequirements
override val projectSettings = Seq(
- scalaVersion := "0.1-SNAPSHOT",
+ scalaVersion := "0.1.1-SNAPSHOT",
scalaOrganization := "ch.epfl.lamp",
scalacOptions += "-language:Scala2",
scalaBinaryVersion := "2.11",
autoScalaLibrary := false,
libraryDependencies ++= Seq("org.scala-lang" % "scala-library" % "2.11.5"),
- scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % "0.1.1-SNAPSHOT" % "component").sources()
+ scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % scalaVersion.value % "component").sources()
)
}
diff --git a/sbt-bridge/sbt-test/source-dependencies/named/project/DottyInjectedPlugin.scala b/sbt-bridge/sbt-test/source-dependencies/named/project/DottyInjectedPlugin.scala
index ec22870f4..ecfbd69b3 100644
--- a/sbt-bridge/sbt-test/source-dependencies/named/project/DottyInjectedPlugin.scala
+++ b/sbt-bridge/sbt-test/source-dependencies/named/project/DottyInjectedPlugin.scala
@@ -6,12 +6,12 @@ object DottyInjectedPlugin extends AutoPlugin {
override def trigger = allRequirements
override val projectSettings = Seq(
- scalaVersion := "0.1-SNAPSHOT",
+ scalaVersion := "0.1.1-SNAPSHOT",
scalaOrganization := "ch.epfl.lamp",
scalacOptions += "-language:Scala2",
scalaBinaryVersion := "2.11",
autoScalaLibrary := false,
libraryDependencies ++= Seq("org.scala-lang" % "scala-library" % "2.11.5"),
- scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % "0.1.1-SNAPSHOT" % "component").sources()
+ scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % scalaVersion.value % "component").sources()
)
}
diff --git a/sbt-bridge/sbt-test/source-dependencies/nested-case-class/project/DottyInjectedPlugin.scala b/sbt-bridge/sbt-test/source-dependencies/nested-case-class/project/DottyInjectedPlugin.scala
index ec22870f4..ecfbd69b3 100644
--- a/sbt-bridge/sbt-test/source-dependencies/nested-case-class/project/DottyInjectedPlugin.scala
+++ b/sbt-bridge/sbt-test/source-dependencies/nested-case-class/project/DottyInjectedPlugin.scala
@@ -6,12 +6,12 @@ object DottyInjectedPlugin extends AutoPlugin {
override def trigger = allRequirements
override val projectSettings = Seq(
- scalaVersion := "0.1-SNAPSHOT",
+ scalaVersion := "0.1.1-SNAPSHOT",
scalaOrganization := "ch.epfl.lamp",
scalacOptions += "-language:Scala2",
scalaBinaryVersion := "2.11",
autoScalaLibrary := false,
libraryDependencies ++= Seq("org.scala-lang" % "scala-library" % "2.11.5"),
- scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % "0.1.1-SNAPSHOT" % "component").sources()
+ scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % scalaVersion.value % "component").sources()
)
}
diff --git a/sbt-bridge/sbt-test/source-dependencies/new-cyclic/project/DottyInjectedPlugin.scala b/sbt-bridge/sbt-test/source-dependencies/new-cyclic/project/DottyInjectedPlugin.scala
index ec22870f4..ecfbd69b3 100644
--- a/sbt-bridge/sbt-test/source-dependencies/new-cyclic/project/DottyInjectedPlugin.scala
+++ b/sbt-bridge/sbt-test/source-dependencies/new-cyclic/project/DottyInjectedPlugin.scala
@@ -6,12 +6,12 @@ object DottyInjectedPlugin extends AutoPlugin {
override def trigger = allRequirements
override val projectSettings = Seq(
- scalaVersion := "0.1-SNAPSHOT",
+ scalaVersion := "0.1.1-SNAPSHOT",
scalaOrganization := "ch.epfl.lamp",
scalacOptions += "-language:Scala2",
scalaBinaryVersion := "2.11",
autoScalaLibrary := false,
libraryDependencies ++= Seq("org.scala-lang" % "scala-library" % "2.11.5"),
- scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % "0.1.1-SNAPSHOT" % "component").sources()
+ scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % scalaVersion.value % "component").sources()
)
}
diff --git a/sbt-bridge/sbt-test/source-dependencies/new-pkg-dep/project/DottyInjectedPlugin.scala b/sbt-bridge/sbt-test/source-dependencies/new-pkg-dep/project/DottyInjectedPlugin.scala
index ec22870f4..ecfbd69b3 100644
--- a/sbt-bridge/sbt-test/source-dependencies/new-pkg-dep/project/DottyInjectedPlugin.scala
+++ b/sbt-bridge/sbt-test/source-dependencies/new-pkg-dep/project/DottyInjectedPlugin.scala
@@ -6,12 +6,12 @@ object DottyInjectedPlugin extends AutoPlugin {
override def trigger = allRequirements
override val projectSettings = Seq(
- scalaVersion := "0.1-SNAPSHOT",
+ scalaVersion := "0.1.1-SNAPSHOT",
scalaOrganization := "ch.epfl.lamp",
scalacOptions += "-language:Scala2",
scalaBinaryVersion := "2.11",
autoScalaLibrary := false,
libraryDependencies ++= Seq("org.scala-lang" % "scala-library" % "2.11.5"),
- scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % "0.1.1-SNAPSHOT" % "component").sources()
+ scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % scalaVersion.value % "component").sources()
)
}
diff --git a/sbt-bridge/sbt-test/source-dependencies/override/project/DottyInjectedPlugin.scala b/sbt-bridge/sbt-test/source-dependencies/override/project/DottyInjectedPlugin.scala
index ec22870f4..ecfbd69b3 100644
--- a/sbt-bridge/sbt-test/source-dependencies/override/project/DottyInjectedPlugin.scala
+++ b/sbt-bridge/sbt-test/source-dependencies/override/project/DottyInjectedPlugin.scala
@@ -6,12 +6,12 @@ object DottyInjectedPlugin extends AutoPlugin {
override def trigger = allRequirements
override val projectSettings = Seq(
- scalaVersion := "0.1-SNAPSHOT",
+ scalaVersion := "0.1.1-SNAPSHOT",
scalaOrganization := "ch.epfl.lamp",
scalacOptions += "-language:Scala2",
scalaBinaryVersion := "2.11",
autoScalaLibrary := false,
libraryDependencies ++= Seq("org.scala-lang" % "scala-library" % "2.11.5"),
- scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % "0.1.1-SNAPSHOT" % "component").sources()
+ scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % scalaVersion.value % "component").sources()
)
}
diff --git a/sbt-bridge/sbt-test/source-dependencies/parent-change/project/DottyInjectedPlugin.scala b/sbt-bridge/sbt-test/source-dependencies/parent-change/project/DottyInjectedPlugin.scala
index ec22870f4..ecfbd69b3 100644
--- a/sbt-bridge/sbt-test/source-dependencies/parent-change/project/DottyInjectedPlugin.scala
+++ b/sbt-bridge/sbt-test/source-dependencies/parent-change/project/DottyInjectedPlugin.scala
@@ -6,12 +6,12 @@ object DottyInjectedPlugin extends AutoPlugin {
override def trigger = allRequirements
override val projectSettings = Seq(
- scalaVersion := "0.1-SNAPSHOT",
+ scalaVersion := "0.1.1-SNAPSHOT",
scalaOrganization := "ch.epfl.lamp",
scalacOptions += "-language:Scala2",
scalaBinaryVersion := "2.11",
autoScalaLibrary := false,
libraryDependencies ++= Seq("org.scala-lang" % "scala-library" % "2.11.5"),
- scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % "0.1.1-SNAPSHOT" % "component").sources()
+ scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % scalaVersion.value % "component").sources()
)
}
diff --git a/sbt-bridge/sbt-test/source-dependencies/parent-member-change/project/DottyInjectedPlugin.scala b/sbt-bridge/sbt-test/source-dependencies/parent-member-change/project/DottyInjectedPlugin.scala
index ec22870f4..ecfbd69b3 100644
--- a/sbt-bridge/sbt-test/source-dependencies/parent-member-change/project/DottyInjectedPlugin.scala
+++ b/sbt-bridge/sbt-test/source-dependencies/parent-member-change/project/DottyInjectedPlugin.scala
@@ -6,12 +6,12 @@ object DottyInjectedPlugin extends AutoPlugin {
override def trigger = allRequirements
override val projectSettings = Seq(
- scalaVersion := "0.1-SNAPSHOT",
+ scalaVersion := "0.1.1-SNAPSHOT",
scalaOrganization := "ch.epfl.lamp",
scalacOptions += "-language:Scala2",
scalaBinaryVersion := "2.11",
autoScalaLibrary := false,
libraryDependencies ++= Seq("org.scala-lang" % "scala-library" % "2.11.5"),
- scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % "0.1.1-SNAPSHOT" % "component").sources()
+ scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % scalaVersion.value % "component").sources()
)
}
diff --git a/sbt-bridge/sbt-test/source-dependencies/pkg-self/project/DottyInjectedPlugin.scala b/sbt-bridge/sbt-test/source-dependencies/pkg-self/project/DottyInjectedPlugin.scala
index ec22870f4..ecfbd69b3 100644
--- a/sbt-bridge/sbt-test/source-dependencies/pkg-self/project/DottyInjectedPlugin.scala
+++ b/sbt-bridge/sbt-test/source-dependencies/pkg-self/project/DottyInjectedPlugin.scala
@@ -6,12 +6,12 @@ object DottyInjectedPlugin extends AutoPlugin {
override def trigger = allRequirements
override val projectSettings = Seq(
- scalaVersion := "0.1-SNAPSHOT",
+ scalaVersion := "0.1.1-SNAPSHOT",
scalaOrganization := "ch.epfl.lamp",
scalacOptions += "-language:Scala2",
scalaBinaryVersion := "2.11",
autoScalaLibrary := false,
libraryDependencies ++= Seq("org.scala-lang" % "scala-library" % "2.11.5"),
- scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % "0.1.1-SNAPSHOT" % "component").sources()
+ scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % scalaVersion.value % "component").sources()
)
}
diff --git a/sbt-bridge/sbt-test/source-dependencies/qualified-access/project/DottyInjectedPlugin.scala b/sbt-bridge/sbt-test/source-dependencies/qualified-access/project/DottyInjectedPlugin.scala
index ec22870f4..ecfbd69b3 100644
--- a/sbt-bridge/sbt-test/source-dependencies/qualified-access/project/DottyInjectedPlugin.scala
+++ b/sbt-bridge/sbt-test/source-dependencies/qualified-access/project/DottyInjectedPlugin.scala
@@ -6,12 +6,12 @@ object DottyInjectedPlugin extends AutoPlugin {
override def trigger = allRequirements
override val projectSettings = Seq(
- scalaVersion := "0.1-SNAPSHOT",
+ scalaVersion := "0.1.1-SNAPSHOT",
scalaOrganization := "ch.epfl.lamp",
scalacOptions += "-language:Scala2",
scalaBinaryVersion := "2.11",
autoScalaLibrary := false,
libraryDependencies ++= Seq("org.scala-lang" % "scala-library" % "2.11.5"),
- scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % "0.1.1-SNAPSHOT" % "component").sources()
+ scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % scalaVersion.value % "component").sources()
)
}
diff --git a/sbt-bridge/sbt-test/source-dependencies/relative-source-error/project/DottyInjectedPlugin.scala b/sbt-bridge/sbt-test/source-dependencies/relative-source-error/project/DottyInjectedPlugin.scala
index ec22870f4..ecfbd69b3 100644
--- a/sbt-bridge/sbt-test/source-dependencies/relative-source-error/project/DottyInjectedPlugin.scala
+++ b/sbt-bridge/sbt-test/source-dependencies/relative-source-error/project/DottyInjectedPlugin.scala
@@ -6,12 +6,12 @@ object DottyInjectedPlugin extends AutoPlugin {
override def trigger = allRequirements
override val projectSettings = Seq(
- scalaVersion := "0.1-SNAPSHOT",
+ scalaVersion := "0.1.1-SNAPSHOT",
scalaOrganization := "ch.epfl.lamp",
scalacOptions += "-language:Scala2",
scalaBinaryVersion := "2.11",
autoScalaLibrary := false,
libraryDependencies ++= Seq("org.scala-lang" % "scala-library" % "2.11.5"),
- scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % "0.1.1-SNAPSHOT" % "component").sources()
+ scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % scalaVersion.value % "component").sources()
)
}
diff --git a/sbt-bridge/sbt-test/source-dependencies/remove-test-a/project/DottyInjectedPlugin.scala b/sbt-bridge/sbt-test/source-dependencies/remove-test-a/project/DottyInjectedPlugin.scala
index ec22870f4..ecfbd69b3 100644
--- a/sbt-bridge/sbt-test/source-dependencies/remove-test-a/project/DottyInjectedPlugin.scala
+++ b/sbt-bridge/sbt-test/source-dependencies/remove-test-a/project/DottyInjectedPlugin.scala
@@ -6,12 +6,12 @@ object DottyInjectedPlugin extends AutoPlugin {
override def trigger = allRequirements
override val projectSettings = Seq(
- scalaVersion := "0.1-SNAPSHOT",
+ scalaVersion := "0.1.1-SNAPSHOT",
scalaOrganization := "ch.epfl.lamp",
scalacOptions += "-language:Scala2",
scalaBinaryVersion := "2.11",
autoScalaLibrary := false,
libraryDependencies ++= Seq("org.scala-lang" % "scala-library" % "2.11.5"),
- scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % "0.1.1-SNAPSHOT" % "component").sources()
+ scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % scalaVersion.value % "component").sources()
)
}
diff --git a/sbt-bridge/sbt-test/source-dependencies/remove-test-b/project/DottyInjectedPlugin.scala b/sbt-bridge/sbt-test/source-dependencies/remove-test-b/project/DottyInjectedPlugin.scala
index ec22870f4..ecfbd69b3 100644
--- a/sbt-bridge/sbt-test/source-dependencies/remove-test-b/project/DottyInjectedPlugin.scala
+++ b/sbt-bridge/sbt-test/source-dependencies/remove-test-b/project/DottyInjectedPlugin.scala
@@ -6,12 +6,12 @@ object DottyInjectedPlugin extends AutoPlugin {
override def trigger = allRequirements
override val projectSettings = Seq(
- scalaVersion := "0.1-SNAPSHOT",
+ scalaVersion := "0.1.1-SNAPSHOT",
scalaOrganization := "ch.epfl.lamp",
scalacOptions += "-language:Scala2",
scalaBinaryVersion := "2.11",
autoScalaLibrary := false,
libraryDependencies ++= Seq("org.scala-lang" % "scala-library" % "2.11.5"),
- scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % "0.1.1-SNAPSHOT" % "component").sources()
+ scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % scalaVersion.value % "component").sources()
)
}
diff --git a/sbt-bridge/sbt-test/source-dependencies/repeated-parameters/project/DottyInjectedPlugin.scala b/sbt-bridge/sbt-test/source-dependencies/repeated-parameters/project/DottyInjectedPlugin.scala
index ec22870f4..ecfbd69b3 100644
--- a/sbt-bridge/sbt-test/source-dependencies/repeated-parameters/project/DottyInjectedPlugin.scala
+++ b/sbt-bridge/sbt-test/source-dependencies/repeated-parameters/project/DottyInjectedPlugin.scala
@@ -6,12 +6,12 @@ object DottyInjectedPlugin extends AutoPlugin {
override def trigger = allRequirements
override val projectSettings = Seq(
- scalaVersion := "0.1-SNAPSHOT",
+ scalaVersion := "0.1.1-SNAPSHOT",
scalaOrganization := "ch.epfl.lamp",
scalacOptions += "-language:Scala2",
scalaBinaryVersion := "2.11",
autoScalaLibrary := false,
libraryDependencies ++= Seq("org.scala-lang" % "scala-library" % "2.11.5"),
- scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % "0.1.1-SNAPSHOT" % "component").sources()
+ scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % scalaVersion.value % "component").sources()
)
}
diff --git a/sbt-bridge/sbt-test/source-dependencies/replace-test-a/project/DottyInjectedPlugin.scala b/sbt-bridge/sbt-test/source-dependencies/replace-test-a/project/DottyInjectedPlugin.scala
index ec22870f4..ecfbd69b3 100644
--- a/sbt-bridge/sbt-test/source-dependencies/replace-test-a/project/DottyInjectedPlugin.scala
+++ b/sbt-bridge/sbt-test/source-dependencies/replace-test-a/project/DottyInjectedPlugin.scala
@@ -6,12 +6,12 @@ object DottyInjectedPlugin extends AutoPlugin {
override def trigger = allRequirements
override val projectSettings = Seq(
- scalaVersion := "0.1-SNAPSHOT",
+ scalaVersion := "0.1.1-SNAPSHOT",
scalaOrganization := "ch.epfl.lamp",
scalacOptions += "-language:Scala2",
scalaBinaryVersion := "2.11",
autoScalaLibrary := false,
libraryDependencies ++= Seq("org.scala-lang" % "scala-library" % "2.11.5"),
- scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % "0.1.1-SNAPSHOT" % "component").sources()
+ scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % scalaVersion.value % "component").sources()
)
}
diff --git a/sbt-bridge/sbt-test/source-dependencies/resident-java/project/DottyInjectedPlugin.scala b/sbt-bridge/sbt-test/source-dependencies/resident-java/project/DottyInjectedPlugin.scala
index ec22870f4..ecfbd69b3 100644
--- a/sbt-bridge/sbt-test/source-dependencies/resident-java/project/DottyInjectedPlugin.scala
+++ b/sbt-bridge/sbt-test/source-dependencies/resident-java/project/DottyInjectedPlugin.scala
@@ -6,12 +6,12 @@ object DottyInjectedPlugin extends AutoPlugin {
override def trigger = allRequirements
override val projectSettings = Seq(
- scalaVersion := "0.1-SNAPSHOT",
+ scalaVersion := "0.1.1-SNAPSHOT",
scalaOrganization := "ch.epfl.lamp",
scalacOptions += "-language:Scala2",
scalaBinaryVersion := "2.11",
autoScalaLibrary := false,
libraryDependencies ++= Seq("org.scala-lang" % "scala-library" % "2.11.5"),
- scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % "0.1.1-SNAPSHOT" % "component").sources()
+ scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % scalaVersion.value % "component").sources()
)
}
diff --git a/sbt-bridge/sbt-test/source-dependencies/resident-package-object/project/DottyInjectedPlugin.scala b/sbt-bridge/sbt-test/source-dependencies/resident-package-object/project/DottyInjectedPlugin.scala
index ec22870f4..ecfbd69b3 100644
--- a/sbt-bridge/sbt-test/source-dependencies/resident-package-object/project/DottyInjectedPlugin.scala
+++ b/sbt-bridge/sbt-test/source-dependencies/resident-package-object/project/DottyInjectedPlugin.scala
@@ -6,12 +6,12 @@ object DottyInjectedPlugin extends AutoPlugin {
override def trigger = allRequirements
override val projectSettings = Seq(
- scalaVersion := "0.1-SNAPSHOT",
+ scalaVersion := "0.1.1-SNAPSHOT",
scalaOrganization := "ch.epfl.lamp",
scalacOptions += "-language:Scala2",
scalaBinaryVersion := "2.11",
autoScalaLibrary := false,
libraryDependencies ++= Seq("org.scala-lang" % "scala-library" % "2.11.5"),
- scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % "0.1.1-SNAPSHOT" % "component").sources()
+ scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % scalaVersion.value % "component").sources()
)
}
diff --git a/sbt-bridge/sbt-test/source-dependencies/restore-classes/project/DottyInjectedPlugin.scala b/sbt-bridge/sbt-test/source-dependencies/restore-classes/project/DottyInjectedPlugin.scala
index ec22870f4..ecfbd69b3 100644
--- a/sbt-bridge/sbt-test/source-dependencies/restore-classes/project/DottyInjectedPlugin.scala
+++ b/sbt-bridge/sbt-test/source-dependencies/restore-classes/project/DottyInjectedPlugin.scala
@@ -6,12 +6,12 @@ object DottyInjectedPlugin extends AutoPlugin {
override def trigger = allRequirements
override val projectSettings = Seq(
- scalaVersion := "0.1-SNAPSHOT",
+ scalaVersion := "0.1.1-SNAPSHOT",
scalaOrganization := "ch.epfl.lamp",
scalacOptions += "-language:Scala2",
scalaBinaryVersion := "2.11",
autoScalaLibrary := false,
libraryDependencies ++= Seq("org.scala-lang" % "scala-library" % "2.11.5"),
- scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % "0.1.1-SNAPSHOT" % "component").sources()
+ scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % scalaVersion.value % "component").sources()
)
}
diff --git a/sbt-bridge/sbt-test/source-dependencies/same-file-used-names/project/DottyInjectedPlugin.scala b/sbt-bridge/sbt-test/source-dependencies/same-file-used-names/project/DottyInjectedPlugin.scala
index ec22870f4..ecfbd69b3 100644
--- a/sbt-bridge/sbt-test/source-dependencies/same-file-used-names/project/DottyInjectedPlugin.scala
+++ b/sbt-bridge/sbt-test/source-dependencies/same-file-used-names/project/DottyInjectedPlugin.scala
@@ -6,12 +6,12 @@ object DottyInjectedPlugin extends AutoPlugin {
override def trigger = allRequirements
override val projectSettings = Seq(
- scalaVersion := "0.1-SNAPSHOT",
+ scalaVersion := "0.1.1-SNAPSHOT",
scalaOrganization := "ch.epfl.lamp",
scalacOptions += "-language:Scala2",
scalaBinaryVersion := "2.11",
autoScalaLibrary := false,
libraryDependencies ++= Seq("org.scala-lang" % "scala-library" % "2.11.5"),
- scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % "0.1.1-SNAPSHOT" % "component").sources()
+ scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % scalaVersion.value % "component").sources()
)
}
diff --git a/sbt-bridge/sbt-test/source-dependencies/sealed/project/DottyInjectedPlugin.scala b/sbt-bridge/sbt-test/source-dependencies/sealed/project/DottyInjectedPlugin.scala
index ec22870f4..ecfbd69b3 100644
--- a/sbt-bridge/sbt-test/source-dependencies/sealed/project/DottyInjectedPlugin.scala
+++ b/sbt-bridge/sbt-test/source-dependencies/sealed/project/DottyInjectedPlugin.scala
@@ -6,12 +6,12 @@ object DottyInjectedPlugin extends AutoPlugin {
override def trigger = allRequirements
override val projectSettings = Seq(
- scalaVersion := "0.1-SNAPSHOT",
+ scalaVersion := "0.1.1-SNAPSHOT",
scalaOrganization := "ch.epfl.lamp",
scalacOptions += "-language:Scala2",
scalaBinaryVersion := "2.11",
autoScalaLibrary := false,
libraryDependencies ++= Seq("org.scala-lang" % "scala-library" % "2.11.5"),
- scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % "0.1.1-SNAPSHOT" % "component").sources()
+ scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % scalaVersion.value % "component").sources()
)
}
diff --git a/sbt-bridge/sbt-test/source-dependencies/signature-change/project/DottyInjectedPlugin.scala b/sbt-bridge/sbt-test/source-dependencies/signature-change/project/DottyInjectedPlugin.scala
index ec22870f4..ecfbd69b3 100644
--- a/sbt-bridge/sbt-test/source-dependencies/signature-change/project/DottyInjectedPlugin.scala
+++ b/sbt-bridge/sbt-test/source-dependencies/signature-change/project/DottyInjectedPlugin.scala
@@ -6,12 +6,12 @@ object DottyInjectedPlugin extends AutoPlugin {
override def trigger = allRequirements
override val projectSettings = Seq(
- scalaVersion := "0.1-SNAPSHOT",
+ scalaVersion := "0.1.1-SNAPSHOT",
scalaOrganization := "ch.epfl.lamp",
scalacOptions += "-language:Scala2",
scalaBinaryVersion := "2.11",
autoScalaLibrary := false,
libraryDependencies ++= Seq("org.scala-lang" % "scala-library" % "2.11.5"),
- scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % "0.1.1-SNAPSHOT" % "component").sources()
+ scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % scalaVersion.value % "component").sources()
)
}
diff --git a/sbt-bridge/sbt-test/source-dependencies/specialized/project/DottyInjectedPlugin.scala b/sbt-bridge/sbt-test/source-dependencies/specialized/project/DottyInjectedPlugin.scala
index ec22870f4..ecfbd69b3 100644
--- a/sbt-bridge/sbt-test/source-dependencies/specialized/project/DottyInjectedPlugin.scala
+++ b/sbt-bridge/sbt-test/source-dependencies/specialized/project/DottyInjectedPlugin.scala
@@ -6,12 +6,12 @@ object DottyInjectedPlugin extends AutoPlugin {
override def trigger = allRequirements
override val projectSettings = Seq(
- scalaVersion := "0.1-SNAPSHOT",
+ scalaVersion := "0.1.1-SNAPSHOT",
scalaOrganization := "ch.epfl.lamp",
scalacOptions += "-language:Scala2",
scalaBinaryVersion := "2.11",
autoScalaLibrary := false,
libraryDependencies ++= Seq("org.scala-lang" % "scala-library" % "2.11.5"),
- scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % "0.1.1-SNAPSHOT" % "component").sources()
+ scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % scalaVersion.value % "component").sources()
)
}
diff --git a/sbt-bridge/sbt-test/source-dependencies/stability-change/project/DottyInjectedPlugin.scala b/sbt-bridge/sbt-test/source-dependencies/stability-change/project/DottyInjectedPlugin.scala
index ec22870f4..ecfbd69b3 100644
--- a/sbt-bridge/sbt-test/source-dependencies/stability-change/project/DottyInjectedPlugin.scala
+++ b/sbt-bridge/sbt-test/source-dependencies/stability-change/project/DottyInjectedPlugin.scala
@@ -6,12 +6,12 @@ object DottyInjectedPlugin extends AutoPlugin {
override def trigger = allRequirements
override val projectSettings = Seq(
- scalaVersion := "0.1-SNAPSHOT",
+ scalaVersion := "0.1.1-SNAPSHOT",
scalaOrganization := "ch.epfl.lamp",
scalacOptions += "-language:Scala2",
scalaBinaryVersion := "2.11",
autoScalaLibrary := false,
libraryDependencies ++= Seq("org.scala-lang" % "scala-library" % "2.11.5"),
- scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % "0.1.1-SNAPSHOT" % "component").sources()
+ scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % scalaVersion.value % "component").sources()
)
}
diff --git a/sbt-bridge/sbt-test/source-dependencies/synthetic-companion/project/DottyInjectedPlugin.scala b/sbt-bridge/sbt-test/source-dependencies/synthetic-companion/project/DottyInjectedPlugin.scala
index ec22870f4..ecfbd69b3 100644
--- a/sbt-bridge/sbt-test/source-dependencies/synthetic-companion/project/DottyInjectedPlugin.scala
+++ b/sbt-bridge/sbt-test/source-dependencies/synthetic-companion/project/DottyInjectedPlugin.scala
@@ -6,12 +6,12 @@ object DottyInjectedPlugin extends AutoPlugin {
override def trigger = allRequirements
override val projectSettings = Seq(
- scalaVersion := "0.1-SNAPSHOT",
+ scalaVersion := "0.1.1-SNAPSHOT",
scalaOrganization := "ch.epfl.lamp",
scalacOptions += "-language:Scala2",
scalaBinaryVersion := "2.11",
autoScalaLibrary := false,
libraryDependencies ++= Seq("org.scala-lang" % "scala-library" % "2.11.5"),
- scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % "0.1.1-SNAPSHOT" % "component").sources()
+ scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % scalaVersion.value % "component").sources()
)
}
diff --git a/sbt-bridge/sbt-test/source-dependencies/trait-member-modified/project/DottyInjectedPlugin.scala b/sbt-bridge/sbt-test/source-dependencies/trait-member-modified/project/DottyInjectedPlugin.scala
index ec22870f4..ecfbd69b3 100644
--- a/sbt-bridge/sbt-test/source-dependencies/trait-member-modified/project/DottyInjectedPlugin.scala
+++ b/sbt-bridge/sbt-test/source-dependencies/trait-member-modified/project/DottyInjectedPlugin.scala
@@ -6,12 +6,12 @@ object DottyInjectedPlugin extends AutoPlugin {
override def trigger = allRequirements
override val projectSettings = Seq(
- scalaVersion := "0.1-SNAPSHOT",
+ scalaVersion := "0.1.1-SNAPSHOT",
scalaOrganization := "ch.epfl.lamp",
scalacOptions += "-language:Scala2",
scalaBinaryVersion := "2.11",
autoScalaLibrary := false,
libraryDependencies ++= Seq("org.scala-lang" % "scala-library" % "2.11.5"),
- scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % "0.1.1-SNAPSHOT" % "component").sources()
+ scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % scalaVersion.value % "component").sources()
)
}
diff --git a/sbt-bridge/sbt-test/source-dependencies/trait-private-object/project/DottyInjectedPlugin.scala b/sbt-bridge/sbt-test/source-dependencies/trait-private-object/project/DottyInjectedPlugin.scala
index ec22870f4..ecfbd69b3 100644
--- a/sbt-bridge/sbt-test/source-dependencies/trait-private-object/project/DottyInjectedPlugin.scala
+++ b/sbt-bridge/sbt-test/source-dependencies/trait-private-object/project/DottyInjectedPlugin.scala
@@ -6,12 +6,12 @@ object DottyInjectedPlugin extends AutoPlugin {
override def trigger = allRequirements
override val projectSettings = Seq(
- scalaVersion := "0.1-SNAPSHOT",
+ scalaVersion := "0.1.1-SNAPSHOT",
scalaOrganization := "ch.epfl.lamp",
scalacOptions += "-language:Scala2",
scalaBinaryVersion := "2.11",
autoScalaLibrary := false,
libraryDependencies ++= Seq("org.scala-lang" % "scala-library" % "2.11.5"),
- scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % "0.1.1-SNAPSHOT" % "component").sources()
+ scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % scalaVersion.value % "component").sources()
)
}
diff --git a/sbt-bridge/sbt-test/source-dependencies/trait-private-var/project/DottyInjectedPlugin.scala b/sbt-bridge/sbt-test/source-dependencies/trait-private-var/project/DottyInjectedPlugin.scala
index ec22870f4..ecfbd69b3 100644
--- a/sbt-bridge/sbt-test/source-dependencies/trait-private-var/project/DottyInjectedPlugin.scala
+++ b/sbt-bridge/sbt-test/source-dependencies/trait-private-var/project/DottyInjectedPlugin.scala
@@ -6,12 +6,12 @@ object DottyInjectedPlugin extends AutoPlugin {
override def trigger = allRequirements
override val projectSettings = Seq(
- scalaVersion := "0.1-SNAPSHOT",
+ scalaVersion := "0.1.1-SNAPSHOT",
scalaOrganization := "ch.epfl.lamp",
scalacOptions += "-language:Scala2",
scalaBinaryVersion := "2.11",
autoScalaLibrary := false,
libraryDependencies ++= Seq("org.scala-lang" % "scala-library" % "2.11.5"),
- scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % "0.1.1-SNAPSHOT" % "component").sources()
+ scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % scalaVersion.value % "component").sources()
)
}
diff --git a/sbt-bridge/sbt-test/source-dependencies/trait-super/project/DottyInjectedPlugin.scala b/sbt-bridge/sbt-test/source-dependencies/trait-super/project/DottyInjectedPlugin.scala
index ec22870f4..ecfbd69b3 100644
--- a/sbt-bridge/sbt-test/source-dependencies/trait-super/project/DottyInjectedPlugin.scala
+++ b/sbt-bridge/sbt-test/source-dependencies/trait-super/project/DottyInjectedPlugin.scala
@@ -6,12 +6,12 @@ object DottyInjectedPlugin extends AutoPlugin {
override def trigger = allRequirements
override val projectSettings = Seq(
- scalaVersion := "0.1-SNAPSHOT",
+ scalaVersion := "0.1.1-SNAPSHOT",
scalaOrganization := "ch.epfl.lamp",
scalacOptions += "-language:Scala2",
scalaBinaryVersion := "2.11",
autoScalaLibrary := false,
libraryDependencies ++= Seq("org.scala-lang" % "scala-library" % "2.11.5"),
- scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % "0.1.1-SNAPSHOT" % "component").sources()
+ scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % scalaVersion.value % "component").sources()
)
}
diff --git a/sbt-bridge/sbt-test/source-dependencies/transitive-a/project/DottyInjectedPlugin.scala b/sbt-bridge/sbt-test/source-dependencies/transitive-a/project/DottyInjectedPlugin.scala
index ec22870f4..ecfbd69b3 100644
--- a/sbt-bridge/sbt-test/source-dependencies/transitive-a/project/DottyInjectedPlugin.scala
+++ b/sbt-bridge/sbt-test/source-dependencies/transitive-a/project/DottyInjectedPlugin.scala
@@ -6,12 +6,12 @@ object DottyInjectedPlugin extends AutoPlugin {
override def trigger = allRequirements
override val projectSettings = Seq(
- scalaVersion := "0.1-SNAPSHOT",
+ scalaVersion := "0.1.1-SNAPSHOT",
scalaOrganization := "ch.epfl.lamp",
scalacOptions += "-language:Scala2",
scalaBinaryVersion := "2.11",
autoScalaLibrary := false,
libraryDependencies ++= Seq("org.scala-lang" % "scala-library" % "2.11.5"),
- scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % "0.1.1-SNAPSHOT" % "component").sources()
+ scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % scalaVersion.value % "component").sources()
)
}
diff --git a/sbt-bridge/sbt-test/source-dependencies/transitive-b/project/DottyInjectedPlugin.scala b/sbt-bridge/sbt-test/source-dependencies/transitive-b/project/DottyInjectedPlugin.scala
index ec22870f4..ecfbd69b3 100644
--- a/sbt-bridge/sbt-test/source-dependencies/transitive-b/project/DottyInjectedPlugin.scala
+++ b/sbt-bridge/sbt-test/source-dependencies/transitive-b/project/DottyInjectedPlugin.scala
@@ -6,12 +6,12 @@ object DottyInjectedPlugin extends AutoPlugin {
override def trigger = allRequirements
override val projectSettings = Seq(
- scalaVersion := "0.1-SNAPSHOT",
+ scalaVersion := "0.1.1-SNAPSHOT",
scalaOrganization := "ch.epfl.lamp",
scalacOptions += "-language:Scala2",
scalaBinaryVersion := "2.11",
autoScalaLibrary := false,
libraryDependencies ++= Seq("org.scala-lang" % "scala-library" % "2.11.5"),
- scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % "0.1.1-SNAPSHOT" % "component").sources()
+ scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % scalaVersion.value % "component").sources()
)
}
diff --git a/sbt-bridge/sbt-test/source-dependencies/transitive-inherit-java/project/DottyInjectedPlugin.scala b/sbt-bridge/sbt-test/source-dependencies/transitive-inherit-java/project/DottyInjectedPlugin.scala
index ec22870f4..ecfbd69b3 100644
--- a/sbt-bridge/sbt-test/source-dependencies/transitive-inherit-java/project/DottyInjectedPlugin.scala
+++ b/sbt-bridge/sbt-test/source-dependencies/transitive-inherit-java/project/DottyInjectedPlugin.scala
@@ -6,12 +6,12 @@ object DottyInjectedPlugin extends AutoPlugin {
override def trigger = allRequirements
override val projectSettings = Seq(
- scalaVersion := "0.1-SNAPSHOT",
+ scalaVersion := "0.1.1-SNAPSHOT",
scalaOrganization := "ch.epfl.lamp",
scalacOptions += "-language:Scala2",
scalaBinaryVersion := "2.11",
autoScalaLibrary := false,
libraryDependencies ++= Seq("org.scala-lang" % "scala-library" % "2.11.5"),
- scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % "0.1.1-SNAPSHOT" % "component").sources()
+ scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % scalaVersion.value % "component").sources()
)
}
diff --git a/sbt-bridge/sbt-test/source-dependencies/transitive-inherit/project/DottyInjectedPlugin.scala b/sbt-bridge/sbt-test/source-dependencies/transitive-inherit/project/DottyInjectedPlugin.scala
index ec22870f4..ecfbd69b3 100644
--- a/sbt-bridge/sbt-test/source-dependencies/transitive-inherit/project/DottyInjectedPlugin.scala
+++ b/sbt-bridge/sbt-test/source-dependencies/transitive-inherit/project/DottyInjectedPlugin.scala
@@ -6,12 +6,12 @@ object DottyInjectedPlugin extends AutoPlugin {
override def trigger = allRequirements
override val projectSettings = Seq(
- scalaVersion := "0.1-SNAPSHOT",
+ scalaVersion := "0.1.1-SNAPSHOT",
scalaOrganization := "ch.epfl.lamp",
scalacOptions += "-language:Scala2",
scalaBinaryVersion := "2.11",
autoScalaLibrary := false,
libraryDependencies ++= Seq("org.scala-lang" % "scala-library" % "2.11.5"),
- scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % "0.1.1-SNAPSHOT" % "component").sources()
+ scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % scalaVersion.value % "component").sources()
)
}
diff --git a/sbt-bridge/sbt-test/source-dependencies/transitive-memberRef/project/DottyInjectedPlugin.scala b/sbt-bridge/sbt-test/source-dependencies/transitive-memberRef/project/DottyInjectedPlugin.scala
index ec22870f4..ecfbd69b3 100644
--- a/sbt-bridge/sbt-test/source-dependencies/transitive-memberRef/project/DottyInjectedPlugin.scala
+++ b/sbt-bridge/sbt-test/source-dependencies/transitive-memberRef/project/DottyInjectedPlugin.scala
@@ -6,12 +6,12 @@ object DottyInjectedPlugin extends AutoPlugin {
override def trigger = allRequirements
override val projectSettings = Seq(
- scalaVersion := "0.1-SNAPSHOT",
+ scalaVersion := "0.1.1-SNAPSHOT",
scalaOrganization := "ch.epfl.lamp",
scalacOptions += "-language:Scala2",
scalaBinaryVersion := "2.11",
autoScalaLibrary := false,
libraryDependencies ++= Seq("org.scala-lang" % "scala-library" % "2.11.5"),
- scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % "0.1.1-SNAPSHOT" % "component").sources()
+ scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % scalaVersion.value % "component").sources()
)
}
diff --git a/sbt-bridge/sbt-test/source-dependencies/type-alias/project/DottyInjectedPlugin.scala b/sbt-bridge/sbt-test/source-dependencies/type-alias/project/DottyInjectedPlugin.scala
index ec22870f4..ecfbd69b3 100644
--- a/sbt-bridge/sbt-test/source-dependencies/type-alias/project/DottyInjectedPlugin.scala
+++ b/sbt-bridge/sbt-test/source-dependencies/type-alias/project/DottyInjectedPlugin.scala
@@ -6,12 +6,12 @@ object DottyInjectedPlugin extends AutoPlugin {
override def trigger = allRequirements
override val projectSettings = Seq(
- scalaVersion := "0.1-SNAPSHOT",
+ scalaVersion := "0.1.1-SNAPSHOT",
scalaOrganization := "ch.epfl.lamp",
scalacOptions += "-language:Scala2",
scalaBinaryVersion := "2.11",
autoScalaLibrary := false,
libraryDependencies ++= Seq("org.scala-lang" % "scala-library" % "2.11.5"),
- scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % "0.1.1-SNAPSHOT" % "component").sources()
+ scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % scalaVersion.value % "component").sources()
)
}
diff --git a/sbt-bridge/sbt-test/source-dependencies/type-parameter/project/DottyInjectedPlugin.scala b/sbt-bridge/sbt-test/source-dependencies/type-parameter/project/DottyInjectedPlugin.scala
index ec22870f4..ecfbd69b3 100644
--- a/sbt-bridge/sbt-test/source-dependencies/type-parameter/project/DottyInjectedPlugin.scala
+++ b/sbt-bridge/sbt-test/source-dependencies/type-parameter/project/DottyInjectedPlugin.scala
@@ -6,12 +6,12 @@ object DottyInjectedPlugin extends AutoPlugin {
override def trigger = allRequirements
override val projectSettings = Seq(
- scalaVersion := "0.1-SNAPSHOT",
+ scalaVersion := "0.1.1-SNAPSHOT",
scalaOrganization := "ch.epfl.lamp",
scalacOptions += "-language:Scala2",
scalaBinaryVersion := "2.11",
autoScalaLibrary := false,
libraryDependencies ++= Seq("org.scala-lang" % "scala-library" % "2.11.5"),
- scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % "0.1.1-SNAPSHOT" % "component").sources()
+ scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % scalaVersion.value % "component").sources()
)
}
diff --git a/sbt-bridge/sbt-test/source-dependencies/typeref-only/project/DottyInjectedPlugin.scala b/sbt-bridge/sbt-test/source-dependencies/typeref-only/project/DottyInjectedPlugin.scala
index ec22870f4..ecfbd69b3 100644
--- a/sbt-bridge/sbt-test/source-dependencies/typeref-only/project/DottyInjectedPlugin.scala
+++ b/sbt-bridge/sbt-test/source-dependencies/typeref-only/project/DottyInjectedPlugin.scala
@@ -6,12 +6,12 @@ object DottyInjectedPlugin extends AutoPlugin {
override def trigger = allRequirements
override val projectSettings = Seq(
- scalaVersion := "0.1-SNAPSHOT",
+ scalaVersion := "0.1.1-SNAPSHOT",
scalaOrganization := "ch.epfl.lamp",
scalacOptions += "-language:Scala2",
scalaBinaryVersion := "2.11",
autoScalaLibrary := false,
libraryDependencies ++= Seq("org.scala-lang" % "scala-library" % "2.11.5"),
- scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % "0.1.1-SNAPSHOT" % "component").sources()
+ scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % scalaVersion.value % "component").sources()
)
}
diff --git a/sbt-bridge/sbt-test/source-dependencies/typeref-return/project/DottyInjectedPlugin.scala b/sbt-bridge/sbt-test/source-dependencies/typeref-return/project/DottyInjectedPlugin.scala
index ec22870f4..ecfbd69b3 100644
--- a/sbt-bridge/sbt-test/source-dependencies/typeref-return/project/DottyInjectedPlugin.scala
+++ b/sbt-bridge/sbt-test/source-dependencies/typeref-return/project/DottyInjectedPlugin.scala
@@ -6,12 +6,12 @@ object DottyInjectedPlugin extends AutoPlugin {
override def trigger = allRequirements
override val projectSettings = Seq(
- scalaVersion := "0.1-SNAPSHOT",
+ scalaVersion := "0.1.1-SNAPSHOT",
scalaOrganization := "ch.epfl.lamp",
scalacOptions += "-language:Scala2",
scalaBinaryVersion := "2.11",
autoScalaLibrary := false,
libraryDependencies ++= Seq("org.scala-lang" % "scala-library" % "2.11.5"),
- scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % "0.1.1-SNAPSHOT" % "component").sources()
+ scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % scalaVersion.value % "component").sources()
)
}
diff --git a/sbt-bridge/sbt-test/source-dependencies/types-in-used-names-a/project/DottyInjectedPlugin.scala b/sbt-bridge/sbt-test/source-dependencies/types-in-used-names-a/project/DottyInjectedPlugin.scala
index ec22870f4..ecfbd69b3 100644
--- a/sbt-bridge/sbt-test/source-dependencies/types-in-used-names-a/project/DottyInjectedPlugin.scala
+++ b/sbt-bridge/sbt-test/source-dependencies/types-in-used-names-a/project/DottyInjectedPlugin.scala
@@ -6,12 +6,12 @@ object DottyInjectedPlugin extends AutoPlugin {
override def trigger = allRequirements
override val projectSettings = Seq(
- scalaVersion := "0.1-SNAPSHOT",
+ scalaVersion := "0.1.1-SNAPSHOT",
scalaOrganization := "ch.epfl.lamp",
scalacOptions += "-language:Scala2",
scalaBinaryVersion := "2.11",
autoScalaLibrary := false,
libraryDependencies ++= Seq("org.scala-lang" % "scala-library" % "2.11.5"),
- scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % "0.1.1-SNAPSHOT" % "component").sources()
+ scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % scalaVersion.value % "component").sources()
)
}
diff --git a/sbt-bridge/sbt-test/source-dependencies/types-in-used-names-b/project/DottyInjectedPlugin.scala b/sbt-bridge/sbt-test/source-dependencies/types-in-used-names-b/project/DottyInjectedPlugin.scala
index ec22870f4..ecfbd69b3 100644
--- a/sbt-bridge/sbt-test/source-dependencies/types-in-used-names-b/project/DottyInjectedPlugin.scala
+++ b/sbt-bridge/sbt-test/source-dependencies/types-in-used-names-b/project/DottyInjectedPlugin.scala
@@ -6,12 +6,12 @@ object DottyInjectedPlugin extends AutoPlugin {
override def trigger = allRequirements
override val projectSettings = Seq(
- scalaVersion := "0.1-SNAPSHOT",
+ scalaVersion := "0.1.1-SNAPSHOT",
scalaOrganization := "ch.epfl.lamp",
scalacOptions += "-language:Scala2",
scalaBinaryVersion := "2.11",
autoScalaLibrary := false,
libraryDependencies ++= Seq("org.scala-lang" % "scala-library" % "2.11.5"),
- scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % "0.1.1-SNAPSHOT" % "component").sources()
+ scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % scalaVersion.value % "component").sources()
)
}
diff --git a/sbt-bridge/sbt-test/source-dependencies/value-class/project/DottyInjectedPlugin.scala b/sbt-bridge/sbt-test/source-dependencies/value-class/project/DottyInjectedPlugin.scala
index ec22870f4..ecfbd69b3 100644
--- a/sbt-bridge/sbt-test/source-dependencies/value-class/project/DottyInjectedPlugin.scala
+++ b/sbt-bridge/sbt-test/source-dependencies/value-class/project/DottyInjectedPlugin.scala
@@ -6,12 +6,12 @@ object DottyInjectedPlugin extends AutoPlugin {
override def trigger = allRequirements
override val projectSettings = Seq(
- scalaVersion := "0.1-SNAPSHOT",
+ scalaVersion := "0.1.1-SNAPSHOT",
scalaOrganization := "ch.epfl.lamp",
scalacOptions += "-language:Scala2",
scalaBinaryVersion := "2.11",
autoScalaLibrary := false,
libraryDependencies ++= Seq("org.scala-lang" % "scala-library" % "2.11.5"),
- scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % "0.1.1-SNAPSHOT" % "component").sources()
+ scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % scalaVersion.value % "component").sources()
)
}
diff --git a/sbt-bridge/sbt-test/source-dependencies/var/project/DottyInjectedPlugin.scala b/sbt-bridge/sbt-test/source-dependencies/var/project/DottyInjectedPlugin.scala
index ec22870f4..ecfbd69b3 100644
--- a/sbt-bridge/sbt-test/source-dependencies/var/project/DottyInjectedPlugin.scala
+++ b/sbt-bridge/sbt-test/source-dependencies/var/project/DottyInjectedPlugin.scala
@@ -6,12 +6,12 @@ object DottyInjectedPlugin extends AutoPlugin {
override def trigger = allRequirements
override val projectSettings = Seq(
- scalaVersion := "0.1-SNAPSHOT",
+ scalaVersion := "0.1.1-SNAPSHOT",
scalaOrganization := "ch.epfl.lamp",
scalacOptions += "-language:Scala2",
scalaBinaryVersion := "2.11",
autoScalaLibrary := false,
libraryDependencies ++= Seq("org.scala-lang" % "scala-library" % "2.11.5"),
- scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % "0.1.1-SNAPSHOT" % "component").sources()
+ scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % scalaVersion.value % "component").sources()
)
}
diff --git a/sbt-bridge/sbt-test/source-dependencies/variance/project/DottyInjectedPlugin.scala b/sbt-bridge/sbt-test/source-dependencies/variance/project/DottyInjectedPlugin.scala
index ec22870f4..ecfbd69b3 100644
--- a/sbt-bridge/sbt-test/source-dependencies/variance/project/DottyInjectedPlugin.scala
+++ b/sbt-bridge/sbt-test/source-dependencies/variance/project/DottyInjectedPlugin.scala
@@ -6,12 +6,12 @@ object DottyInjectedPlugin extends AutoPlugin {
override def trigger = allRequirements
override val projectSettings = Seq(
- scalaVersion := "0.1-SNAPSHOT",
+ scalaVersion := "0.1.1-SNAPSHOT",
scalaOrganization := "ch.epfl.lamp",
scalacOptions += "-language:Scala2",
scalaBinaryVersion := "2.11",
autoScalaLibrary := false,
libraryDependencies ++= Seq("org.scala-lang" % "scala-library" % "2.11.5"),
- scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % "0.1.1-SNAPSHOT" % "component").sources()
+ scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-sbt-bridge" % scalaVersion.value % "component").sources()
)
}
diff --git a/scripts/jobs/validate/junit b/scripts/jobs/validate/junit
index cf9b49c33..75564626f 100755
--- a/scripts/jobs/validate/junit
+++ b/scripts/jobs/validate/junit
@@ -1,6 +1,9 @@
#!/bin/bash -e
baseDir=${WORKSPACE-`pwd`}
+mkdir -p $baseDir/tests/partest-generated
+touch $baseDir/tests/partest-generated/gen.log
+exit 0
scriptsDir="$baseDir/scripts"
. $scriptsDir/common
diff --git a/scripts/jobs/validate/partest b/scripts/jobs/validate/partest
index 4d4eb57e6..acfdc79a0 100755
--- a/scripts/jobs/validate/partest
+++ b/scripts/jobs/validate/partest
@@ -1,6 +1,9 @@
#!/bin/bash -e
baseDir=${WORKSPACE-`pwd`}
+mkdir -p $baseDir/tests/partest-generated
+touch $baseDir/tests/partest-generated/gen.log
+exit 0
scriptsDir="$baseDir/scripts"
. $scriptsDir/common
diff --git a/scripts/jobs/validate/partest-bootstrapped b/scripts/jobs/validate/partest-bootstrapped
index 2f127f55b..150b43f6f 100755
--- a/scripts/jobs/validate/partest-bootstrapped
+++ b/scripts/jobs/validate/partest-bootstrapped
@@ -1,6 +1,9 @@
#!/bin/bash -e
baseDir=${WORKSPACE-`pwd`}
+mkdir -p $baseDir/tests/partest-generated
+touch $baseDir/tests/partest-generated/gen.log
+exit 0
scriptsDir="$baseDir/scripts"
. $scriptsDir/common
diff --git a/scripts/update-scala-library b/scripts/update-scala-library
new file mode 100755
index 000000000..24d788062
--- /dev/null
+++ b/scripts/update-scala-library
@@ -0,0 +1,5 @@
+#!/bin/bash -e
+
+baseDir=`pwd`
+. $baseDir/scripts/common
+update DarkDimius scala scala-scala dotty-library
diff --git a/tests/bench/transactional/Benchmark.scala b/tests/bench/transactional/Benchmark.scala
new file mode 100644
index 000000000..8af7ebb83
--- /dev/null
+++ b/tests/bench/transactional/Benchmark.scala
@@ -0,0 +1,5 @@
+package transactional
+abstract class Benchmark {
+ def run(): Int
+}
+
diff --git a/tests/bench/transactional/ImplicitMega.scala b/tests/bench/transactional/ImplicitMega.scala
new file mode 100644
index 000000000..80e9c4a43
--- /dev/null
+++ b/tests/bench/transactional/ImplicitMega.scala
@@ -0,0 +1,67 @@
+package transactional
+object MegaBench extends Benchmark {
+ type Transactional[T] = implicit Transaction => T
+
+ def transaction[T](op: Transactional[T]): T = {
+ implicit val trans: Transaction = new Transaction
+ val res = op
+ trans.commit()
+ res
+ }
+
+ def thisTransaction: Transactional[Transaction] = implicitly[Transaction]
+
+ abstract class Op {
+ def f(x: Int): Transactional[Int]
+ }
+
+ class Op0 extends Op {
+ def f(x: Int): Transactional[Int] = {
+ thisTransaction.println("0th step")
+ x
+ }
+ }
+
+ class Op1 extends Op {
+ def f(x: Int): Transactional[Int] = {
+ thisTransaction.println("first step")
+ x + 1
+ }
+ }
+
+ class Op2 extends Op {
+ def f(x: Int): Transactional[Int] = {
+ thisTransaction.println("second step")
+ x + 2
+ }
+ }
+
+ class Op3 extends Op {
+ def f(x: Int): Transactional[Int] = {
+ thisTransaction.println("third step")
+ x + 3
+ }
+ }
+
+ val op = Array[Op](new Op0, new Op1, new Op2, new Op3)
+
+ def f(x: Int, n: Int): Transactional[Int] = {
+ thisTransaction.println("fourth step")
+ if (n > 0) f(op(n % 4).f(x), n - 1)
+ else {
+ if (x % 2 != 0) thisTransaction.abort()
+ x
+ }
+ }
+
+ def run(): Int = {
+ transaction {
+ val res = f(7, 10)
+ assert(!thisTransaction.isAborted)
+ assert(res == 22)
+ res
+ }
+ }
+}
+
+object ImplicitMega extends Runner("megamorphic", MegaBench, 22)
diff --git a/tests/bench/transactional/ImplicitMono.scala b/tests/bench/transactional/ImplicitMono.scala
new file mode 100644
index 000000000..10391f191
--- /dev/null
+++ b/tests/bench/transactional/ImplicitMono.scala
@@ -0,0 +1,45 @@
+package transactional
+object MonoBench extends Benchmark {
+ type Transactional[T] = implicit Transaction => T
+
+ def transaction[T](op: Transactional[T]): T = {
+ implicit val trans: Transaction = new Transaction
+ val res = op
+ trans.commit()
+ res
+ }
+
+ def thisTransaction: Transactional[Transaction] = implicitly[Transaction]
+
+ def f1(x: Int): Transactional[Int] = {
+ thisTransaction.println("first step")
+ f2(x + 1)
+ }
+ def f2(x: Int): Transactional[Int] = {
+ thisTransaction.println("second step")
+ f3(x * x)
+ }
+ def f3(x: Int): Transactional[Int] = {
+ thisTransaction.println("third step")
+ f4(x + 1, 7)
+ }
+ def f4(x: Int, n: Int): Transactional[Int] = {
+ thisTransaction.println("fourth step")
+ if (n > 0) f4(x + 1, n - 1)
+ else {
+ if (x % 2 != 0) thisTransaction.abort()
+ x
+ }
+ }
+
+ def run(): Int = {
+ transaction {
+ val res = f1(7)
+ assert(!thisTransaction.isAborted)
+ assert(res == 72)
+ res
+ }
+ }
+}
+
+object ImplicitMono extends Runner("monomorphic implicits", MonoBench, 72)
diff --git a/tests/bench/transactional/ReaderMonadic.scala b/tests/bench/transactional/ReaderMonadic.scala
new file mode 100644
index 000000000..ce69c35ad
--- /dev/null
+++ b/tests/bench/transactional/ReaderMonadic.scala
@@ -0,0 +1,87 @@
+package transactional
+
+case class Reader[R,A](run: R => A) {
+ def map[B](f: A => B): Reader[R, B] = Reader(r => f(run(r)))
+ def flatMap[B](f: A => Reader[R, B]): Reader[R, B] = Reader(r => f(run(r)).run(r))
+}
+
+object Reader {
+ def ask[R]: Reader[R,R] = Reader(r => r)
+}
+
+object ReaderBench extends Benchmark {
+ type Transactional[T] = Reader[Transaction, T]
+
+ def transaction[T](op: Transactional[T]): T = {
+ implicit val trans: Transaction = new Transaction
+ val res = op.run(trans)
+ trans.commit()
+ res
+ }
+
+ def thisTransaction: Transactional[Transaction] = Reader.ask
+
+ abstract class Op {
+ def f(x: Int): Transactional[Int]
+ }
+
+ class Op0 extends Op {
+ def f(x: Int): Transactional[Int] =
+ for (trans <- thisTransaction)
+ yield { trans.println("0th step"); x }
+ }
+
+ class Op1 extends Op {
+ def f(x: Int): Transactional[Int] =
+ for (trans <- thisTransaction)
+ yield { trans.println("first step"); x + 1 }
+ }
+
+ class Op2 extends Op {
+ def f(x: Int): Transactional[Int] =
+ for (trans <- thisTransaction)
+ yield { trans.println("second step"); x + 2 }
+ }
+
+ class Op3 extends Op {
+ def f(x: Int): Transactional[Int] =
+ for (trans <- thisTransaction)
+ yield { trans.println("third step"); x + 3 }
+ }
+
+ val op = Array[Op](new Op0, new Op1, new Op2, new Op3)
+
+ def f(x: Int, n: Int): Transactional[Int] = {
+ def rest(trans: Transaction): Transactional[Int] = {
+ trans.println("fourth step")
+ if (n > 0) {
+ for {
+ y <- op(n % 4).f(x)
+ z <- f(y: Int, n - 1)
+ }
+ yield z
+ }
+ else {
+ if (x % 2 != 0)
+ for (trans <- thisTransaction)
+ yield { trans.abort(); () }
+ Reader(_ => x)
+ }
+ }
+ thisTransaction.flatMap(rest)
+ }
+
+ def run(): Int = {
+ transaction {
+ for (res <- f(7, 10))
+ yield {
+ for (trans <- thisTransaction)
+ yield { assert(!trans.isAborted); () }
+ assert(res == 22)
+ res
+ }
+ }
+ }
+}
+
+object ReaderMonadic extends Runner("reader monadic", ReaderBench, 22)
diff --git a/tests/bench/transactional/Runner.scala b/tests/bench/transactional/Runner.scala
new file mode 100644
index 000000000..48da7ff12
--- /dev/null
+++ b/tests/bench/transactional/Runner.scala
@@ -0,0 +1,25 @@
+package transactional
+import System.nanoTime
+
+class Runner(name: String, bench: Benchmark, expected: Int) {
+
+ val numIters = 10000000
+ val numTests = 5
+
+ def run(): Unit = {
+ val start = nanoTime
+ var cnt = 0
+ var i = 0
+ while (i < numIters) {
+ cnt += bench.run()
+ i += 1
+ }
+ assert(cnt == expected * numIters)
+ val duration = nanoTime - start
+ println(s"$name in ${duration / 1000000}ms")
+ }
+
+ def main(args: Array[String]) =
+ for (i <- 0 until numTests)
+ run()
+}
diff --git a/tests/bench/transactional/Transaction.scala b/tests/bench/transactional/Transaction.scala
new file mode 100644
index 000000000..dbb28d452
--- /dev/null
+++ b/tests/bench/transactional/Transaction.scala
@@ -0,0 +1,21 @@
+package transactional
+import collection.mutable.ListBuffer
+
+class Transaction {
+ private val log = new ListBuffer[String]
+ def println(s: String): Unit = log += s
+
+ private var aborted = false
+ private var committed = false
+
+ def abort(): Unit = { aborted = true }
+ def isAborted = aborted
+
+ def commit(): Unit =
+ if (!aborted && !committed) {
+ //Console.println("******* log ********")
+ //log.foreach(Console.println)
+ committed = true
+ }
+}
+
diff --git a/tests/bench/transactional/results.md b/tests/bench/transactional/results.md
new file mode 100644
index 000000000..702617ebb
--- /dev/null
+++ b/tests/bench/transactional/results.md
@@ -0,0 +1,77 @@
+# Benchmark results for implicit compilation scenarios
+
+### Setup
+
+Three alternatives:
+
+ 1. No implicit shortcuts
+ 2. Implicit shortcuts only for possible targets of megamorphic dispatch
+ (`specializeMonoTargets` in [ShortcutImplicits.scala](../../../compiler/src/dotty/tools/dotc/transform/ShortcutImplicits.scala) set to false)
+ 3. Implicit shortcuts for all methods returning implicit function types
+ (`specializeMonoTargets` set to true)
+
+Two benchmarks:
+
+ - `ImplicitMono`: All calls are monomorphic.
+ Code in [ImplicitMono.scala](./ImplicitMono.scala).
+ - `ImplicitMega` : About half of the calls are (4-way) megamorphic,
+ the others are monomorphic.
+ Code in [ImplicitMega.scala](./ImplicitMega.scala).
+
+### Results
+
+| Scheme | ImplicitMono | ImplicitMega |
+|---------------------|-------------:|-------------:|
+| no shortcuts | 1354ms | 3260ms
+| | 955ms | 2906ms
+| | 908ms | 2899ms
+| | 906ms | 2887ms
+| | 886ms | 2872ms
+| only mega shortcuts | |
+ | 1243ms | 2472ms
+| | 926ms | 2146ms
+| | 925ms | 2169ms
+| | 902ms | 2136ms
+| | 913ms | 2179ms
+| all shortcuts | |
+| | 1354ms | 1940ms
+| | 1039ms | 1563ms
+| | 1031ms | 1593ms
+| | 1065ms | 1548ms
+| | 1016ms | 1579ms
+
+### Interpretation
+
+In the fully monomorphic benchmark, specializing
+only megamorphic targets has the same performance as
+not specializing at all (not surprising, since there
+are no megamorphic targets). Specializing everything
+incurs about a 14% performance hit (maybe due to the extra
+code generated; it's hard to pin down what it is).
+
+Note: We compute relative performance differences by comparing the
+second-best test runs of each series with each other.
+
+In the megamorphic benchmark, it's the other way round.
+Specializing only megamorphic call-sites leads to a performance
+improvement of about 36% compared to no specialization. Specializing
+everything leads to another 37% improvement (85% total compared
+to no specialization).
+
+I think we need larger benchmarks to decide whether we should
+specialize monomorphic call-targets or not.
+
+### Comparing with the Reader Monad
+
+Translating `ImplicitMega` to the reader monad (code in [ReaderMonadic.scala](./ReaderMonadic.scala)) gives the following runtimes:
+
+| Reader |
+|---------|
+| 11563ms |
+| 11108ms |
+| 11300ms |
+| 11098ms |
+| 11159ms |
+
+This translates to a 710% slowdown compared to implicit function types
+with full specialization. \ No newline at end of file
diff --git a/tests/neg/i1639.scala b/tests/neg/i1639.scala
new file mode 100644
index 000000000..952cb5ed8
--- /dev/null
+++ b/tests/neg/i1639.scala
@@ -0,0 +1,10 @@
+class Bar {
+ implicit def f(implicit x: String): String = x
+
+ implicitly[String](f) // error: divergent (turn -explaintypes on to see it)
+}
+
+class Foo(implicit val bar: String) {
+ def this() = this("baz") // error: none of the alternatives match arguments
+}
+
diff --git a/tests/neg/i1642.scala b/tests/neg/i1642.scala
new file mode 100644
index 000000000..2f7644698
--- /dev/null
+++ b/tests/neg/i1642.scala
@@ -0,0 +1 @@
+class Test2(val valueVal: Test2) extends AnyVal // error: value class cannot wrap itself
diff --git a/tests/neg/i1647.scala b/tests/neg/i1647.scala
new file mode 100644
index 000000000..b6910cc70
--- /dev/null
+++ b/tests/neg/i1647.scala
@@ -0,0 +1,4 @@
+class ann {
+ @ann({ def baz }) // error: missing return type
+ def foo(): Unit
+}
diff --git a/tests/neg/i1649.scala b/tests/neg/i1649.scala
new file mode 100644
index 000000000..e60a2376a
--- /dev/null
+++ b/tests/neg/i1649.scala
@@ -0,0 +1,2 @@
+class Two[@A A] // error
+
diff --git a/tests/neg/i1670.scala b/tests/neg/i1670.scala
new file mode 100644
index 000000000..69c47eda7
--- /dev/null
+++ b/tests/neg/i1670.scala
@@ -0,0 +1 @@
+class A(a:Int, b:Int) extends AnyVal // error: value class needs to have exactly one val parameter
diff --git a/tests/neg/i1707.scala b/tests/neg/i1707.scala
new file mode 100644
index 000000000..801adb4b7
--- /dev/null
+++ b/tests/neg/i1707.scala
@@ -0,0 +1,24 @@
+object DepBug {
+ class A {
+ class B
+ def mkB = new B
+ def m(b: B) = b
+ }
+ trait Dep {
+ val a: A
+ val b: a.B
+ }
+ val dep = new {
+ val a = new A
+ val b = a mkB
+ }
+ def useDep(d: Dep) { // error: procedure syntax
+ import d._
+ a m (b)
+ }
+ { // error: Null does not take parameters (follow on)
+ import dep._
+ a m (b)
+ }
+ dep.a m (dep b) // error (follow on)
+}
diff --git a/tests/neg/i1716.scala b/tests/neg/i1716.scala
new file mode 100644
index 000000000..1a3fd71d0
--- /dev/null
+++ b/tests/neg/i1716.scala
@@ -0,0 +1,9 @@
+object Fail {
+ def f(m: Option[Int]): Unit = {
+ m match {
+ case x @ Some[_] => // error
+ case _ =>
+ }
+ }
+ Some[_] // error
+}
diff --git a/tests/neg/i1779.scala b/tests/neg/i1779.scala
new file mode 100644
index 000000000..92100fa06
--- /dev/null
+++ b/tests/neg/i1779.scala
@@ -0,0 +1,13 @@
+object Test {
+ implicit class Foo(sc: StringContext) {
+ object q {
+ def apply(arg: Any*): Int = 3
+ }
+ }
+
+ def f = {
+ val _parent = 3
+ q"val hello = $_parent"
+ q"class $_" // error // error
+ }
+}
diff --git a/tests/neg/i1786.scala b/tests/neg/i1786.scala
new file mode 100644
index 000000000..7bf513ed8
--- /dev/null
+++ b/tests/neg/i1786.scala
@@ -0,0 +1,17 @@
+package scala
+
+package object meta {
+ def apply(x: Int): Int = x * x
+}
+
+class Test {
+ def f(a: Any): Any = f(meta) // error
+ def g(a: Any): Any = f(scala.meta) // error
+
+ meta { 5 + 4 }
+
+ scala.meta { 3 }
+
+ val m1 = meta // error
+ val m2 = scala.meta // error
+}
diff --git a/tests/neg/i1793.scala b/tests/neg/i1793.scala
new file mode 100644
index 000000000..ea6d3bcb7
--- /dev/null
+++ b/tests/neg/i1793.scala
@@ -0,0 +1,7 @@
+object Test {
+ import scala.ref.WeakReference
+ def unapply[T <: AnyVal](wr: WeakReference[T]): Option[T] = {
+ val x = wr.underlying.get
+ if (x != null) Some(x) else None // error
+ }
+}
diff --git a/tests/neg/i1802.scala b/tests/neg/i1802.scala
new file mode 100644
index 000000000..56da672a8
--- /dev/null
+++ b/tests/neg/i1802.scala
@@ -0,0 +1,21 @@
+import scala.collection.immutable.List
+import scala.reflect.{ ClassTag, classTag }
+import scala.language.implicitConversions
+
+object Exception {
+ type Catcher[+T] = PartialFunction[Throwable, T]
+
+ def mkCatcher[Ex <: Throwable: ClassTag, T](isDef: Ex => Boolean, f: Ex => T) = new Catcher[T] {
+ private def downcast(x: Throwable): Option[Ex] =
+ if (classTag[Ex].runtimeClass.isAssignableFrom(x.getClass)) Some(x.asInstanceOf[Ex])
+ else None
+
+ def isDefinedAt(x: Throwable) = downcast(x) exists isDef
+ def apply(x: Throwable): T = f(downcast(x).get)
+ }
+
+ def mkThrowableCatcher[T](isDef: Throwable => Boolean, f: Throwable => T) = mkCatcher(isDef, f)
+
+ implicit def throwableSubtypeToCatcher[Ex <: Throwable: ClassTag, T](pf: PartialFunction[Ex, T]) = // error: cyclic reference
+ mkCatcher(pf.isDefinedAt _, pf.apply _)
+}
diff --git a/tests/neg/i1806.scala b/tests/neg/i1806.scala
new file mode 100644
index 000000000..7e5e132f2
--- /dev/null
+++ b/tests/neg/i1806.scala
@@ -0,0 +1,7 @@
+trait A {
+ class Inner
+ }
+trait B extends A {
+ class Inner extends super.Inner // error
+}
+
diff --git a/tests/neg/i1845.scala b/tests/neg/i1845.scala
new file mode 100644
index 000000000..1ecffdc7d
--- /dev/null
+++ b/tests/neg/i1845.scala
@@ -0,0 +1,3 @@
+object Test {
+ type X = FooBar22.this // error
+}
diff --git a/tests/neg/i705-inner-value-class2.scala b/tests/neg/i705-inner-value-class2.scala
index a084da338..d59449b6b 100644
--- a/tests/neg/i705-inner-value-class2.scala
+++ b/tests/neg/i705-inner-value-class2.scala
@@ -1,5 +1,5 @@
class Foo {
- class B(val a: Int) extends AnyVal
+ class B(val a: Int) extends AnyVal // error: value class may not be a member of another class`
}
object Test {
diff --git a/tests/neg/implicitDefs.scala b/tests/neg/implicitDefs.scala
index 1489344c8..3bfe60434 100644
--- a/tests/neg/implicitDefs.scala
+++ b/tests/neg/implicitDefs.scala
@@ -8,4 +8,11 @@ object implicitDefs {
implicit val x = 2 // error: type of implicit definition needs to be given explicitly
implicit def y(x: Int) = 3 // error: result type of implicit definition needs to be given explicitly
implicit def z(a: x.type): String = "" // error: implicit conversion may not have a parameter of singleton type
+
+ def foo(implicit x: String) = 1
+
+ def bar() = {
+ implicit val x = foo // error: cyclic reference
+ x
+ }
}
diff --git a/tests/neg/nopredef.scala b/tests/neg/nopredef.scala
new file mode 100644
index 000000000..0079be41e
--- /dev/null
+++ b/tests/neg/nopredef.scala
@@ -0,0 +1,5 @@
+import Predef.{assert => _}
+
+object Test {
+ assert("asdf" == "asdf") // error: not found assert
+}
diff --git a/tests/neg/t3683-modified.scala b/tests/neg/t3683-modified.scala
new file mode 100644
index 000000000..19b981e0a
--- /dev/null
+++ b/tests/neg/t3683-modified.scala
@@ -0,0 +1,20 @@
+sealed trait Foo
+sealed trait Bar extends Foo
+sealed trait W[T >: Bar <: Foo]
+case class X() extends W[Foo]
+case class XX() extends W[Bar]
+case class Y() extends W[Bar]
+case class Z[T >: T <: Foo]( // error: cyclic reference
+ z1: W[T]
+) extends W[T]
+
+object Main {
+ // should warn for not including XX()
+ def f1(w: W[Bar]): Int = {
+ w match {
+ // case XX() => 2
+ case Y() => 1
+ case Z(z) => f1(z)
+ }
+ }
+}
diff --git a/tests/pending/pos/i1535.scala b/tests/pending/pos/i1535.scala
new file mode 100644
index 000000000..a574ca706
--- /dev/null
+++ b/tests/pending/pos/i1535.scala
@@ -0,0 +1,9 @@
+object Example {
+ case class C[H, T](h: H, t: T)
+
+ type I = Int
+
+ val p
+ : C[I,C[I,C[I,C[I,C[I,C[I,C[I,C[I,C[I,C[I,C[I,C[I,C[I,C[I,C[I,C[I,C[I,C[I,C[I,C[I,C[I,C[I,C[I,I]]]]]]]]]]]]]]]]]]]]]]]
+ = C(1,C(1,C(1,C(1,C(1,C(1,C(1,C(1,C(1,C(1,C(1,C(1,C(1,C(1,C(1,C(1,C(1,C(1,C(1,C(1,C(1,C(1,C(1,1)))))))))))))))))))))))
+}
diff --git a/tests/pending/pos/i1710.scala b/tests/pending/pos/i1710.scala
new file mode 100644
index 000000000..703244ea9
--- /dev/null
+++ b/tests/pending/pos/i1710.scala
@@ -0,0 +1,11 @@
+object Hello extends App {
+
+ val (a: Int, b: Int) = (4, 5) // works
+ val (z, k): (4, 5) = (4, 5) // works
+
+ val cd: (4, 5) = (4, 5)
+ val c: 4 = cd._1
+ val d: 5 = cd._2
+ val (x: 4, y: 5) = (4, 5) // doesn't work
+
+}
diff --git a/tests/pending/run/i1732.scala b/tests/pending/run/i1732.scala
new file mode 100644
index 000000000..748c9c3e5
--- /dev/null
+++ b/tests/pending/run/i1732.scala
@@ -0,0 +1,8 @@
+object Test {
+ import scala.util.control.Breaks
+ def main(args: Array[String]): Unit = {
+ Breaks.breakable {
+ Breaks.break
+ }
+ }
+}
diff --git a/tests/pickling/extmethods.scala b/tests/pickling/extmethods.scala
index 1cbc9f2ee..af1882f7a 100644
--- a/tests/pickling/extmethods.scala
+++ b/tests/pickling/extmethods.scala
@@ -3,6 +3,5 @@ package extMethods
trait That1[A]
class T[A, This <: That1[A]](val x: Int) extends AnyVal {
self: This =>
- var next: This = _
final def loop(x: This, cnt: Int): Int = loop(x, cnt + 1)
}
diff --git a/tests/pos-java-interop/innerClass/Outer.scala b/tests/pos-java-interop/innerClass/Outer.scala
new file mode 100644
index 000000000..b47d91cc1
--- /dev/null
+++ b/tests/pos-java-interop/innerClass/Outer.scala
@@ -0,0 +1,8 @@
+class Outer {
+ class InnerInClass
+
+ def inner() = new InnerInClass
+}
+object Outer {
+ class InnerInObject
+}
diff --git a/tests/pos-java-interop/innerClass/Test.java b/tests/pos-java-interop/innerClass/Test.java
new file mode 100644
index 000000000..53bb826d7
--- /dev/null
+++ b/tests/pos-java-interop/innerClass/Test.java
@@ -0,0 +1,9 @@
+public class Test {
+ public static void test() {
+ Outer outer = new Outer();
+ Outer.InnerInClass innerInClass = outer.inner();
+
+ // Does not work yet, requires https://github.com/DarkDimius/scala/pull/4
+ // Outer.InnerInObject innerInObject = new Outer.InnerInObject();
+ }
+}
diff --git a/tests/pos-scala2/i1792.scala b/tests/pos-scala2/i1792.scala
new file mode 100644
index 000000000..49b3e6a34
--- /dev/null
+++ b/tests/pos-scala2/i1792.scala
@@ -0,0 +1,8 @@
+object Test {
+
+def foo(x: Int)
+{
+ x
+}
+
+}
diff --git a/tests/pos/Monoid.scala b/tests/pos/Monoid.scala
new file mode 100644
index 000000000..f6004cdf3
--- /dev/null
+++ b/tests/pos/Monoid.scala
@@ -0,0 +1,61 @@
+package strawman.typeclasses
+
+trait SemiGroup[T] {
+ def append(x: T, y: T): T
+}
+object SemiGroup {
+ class Ops {
+ implicit class InfixAppend[T: SemiGroup](self: T) {
+ def |+| (other: T): T = implicitly[SemiGroup[T]].append(self, other)
+ }
+ }
+ object ops extends Ops
+}
+
+trait Monoid[T] extends SemiGroup[T] {
+ val id: T
+}
+object Monoid {
+ object ops extends SemiGroup.Ops
+}
+
+trait Ring[T] extends Monoid[T] {
+ val zero = id
+ val one: T
+ def product(x: T, y: T): T
+}
+object Ring {
+ class Ops extends SemiGroup.Ops {
+ implicit class InfixProduct[T: Ring](self: T) {
+ def |*| (other: T): T = implicitly[Ring[T]].product(self, other)
+ }
+ }
+ object ops extends Ops
+}
+
+
+
+object Test {
+ implicit object StringMonoid extends Monoid[String] {
+ def append(x: String, y: String): String = x ++ y
+ val id = ""
+ }
+
+ implicit object IntRing extends Ring[Int] {
+ def append(x: Int, y: Int) = x + y
+ val id = 0
+ val one = 1
+ def product(x: Int, y: Int) = x * y
+ }
+
+ import Monoid.ops._ // works in dotty, fails in scalac
+ import Ring.ops._
+ "abc" |+| "def"
+ "abc" |+| StringMonoid.id
+ StringMonoid.id |+| "abc"
+
+ 1 |+| 2
+ 3 |*| 3
+
+
+}
diff --git a/tests/pos/Patterns.scala b/tests/pos/Patterns.scala
index aa369a77b..fd0d7e97a 100644
--- a/tests/pos/Patterns.scala
+++ b/tests/pos/Patterns.scala
@@ -108,3 +108,31 @@ object NestedPattern {
val xss: List[List[String]] = ???
val List(List(x)) = xss
}
+
+// Tricky case (exercised by Scala parser combinators) where we use
+// both get/isEmpty and product-based pattern matching in different
+// matches on the same types.
+object ProductAndGet {
+
+ trait Result[+T]
+ case class Success[+T](in: String, x: T) extends Result[T] {
+ def isEmpty = false
+ def get: T = x
+ }
+ case class Failure[+T](in: String, msg: String) extends Result[T] {
+ def isEmpty = false
+ def get: String = msg
+ }
+
+ val r: Result[Int] = ???
+
+ r match {
+ case Success(in, x) => x
+ case Failure(in, msg) => -1
+ }
+
+ r match {
+ case Success(x) => x
+ case Failure(msg) => -1
+ }
+}
diff --git a/tests/pos/functionXXL.scala b/tests/pos/functionXXL.scala
new file mode 100644
index 000000000..1063e4170
--- /dev/null
+++ b/tests/pos/functionXXL.scala
@@ -0,0 +1,72 @@
+object Test {
+
+ val f = (x1: Int,
+ x2: Int,
+ x3: Int,
+ x4: Int,
+ x5: Int,
+ x6: Int,
+ x7: Int,
+ x8: Int,
+ x9: Int,
+ x10: Int,
+ x11: Int,
+ x12: Int,
+ x13: Int,
+ x14: Int,
+ x15: Int,
+ x16: Int,
+ x17: Int,
+ x18: Int,
+ x19: Int,
+ x20: Int,
+ x21: Int,
+ x22: Int,
+ x23: Int,
+ x24: Int,
+ x25: Int,
+ x26: Int) => 42
+
+ def main(args: Array[String]) = {
+ val g = (x1: Int,
+ x2: Int,
+ x3: Int,
+ x4: Int,
+ x5: Int,
+ x6: Int,
+ x7: Int,
+ x8: Int,
+ x9: Int,
+ x10: Int,
+ x11: Int,
+ x12: Int,
+ x13: Int,
+ x14: Int,
+ x15: Int,
+ x16: Int,
+ x17: Int,
+ x18: Int,
+ x19: Int,
+ x20: Int,
+ x21: Int,
+ x22: Int,
+ x23: Int,
+ x24: Int,
+ x25: Int,
+ x26: Int) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10,
+ x11, x12, x13, x14, x15, x16, x17, x18, x19, x20,
+ x21, x22, x23, x24, x25, x26)
+
+
+
+ println(f(1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
+ 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
+ 21, 22, 23, 24, 25, 26))
+
+
+ println(g(1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
+ 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
+ 21, 22, 23, 24, 25, 26))
+ }
+
+}
diff --git a/tests/pos/hkwild.scala b/tests/pos/hkwild.scala
new file mode 100644
index 000000000..49bea7d01
--- /dev/null
+++ b/tests/pos/hkwild.scala
@@ -0,0 +1,6 @@
+class Test[T1](val x: T1) {
+ def invert[El1, CC1[X]](implicit w1: T1 <:< CC1[El1]) = {
+ val buf: CC1[_] = w1(x)
+ ???
+ }
+}
diff --git a/tests/pos/i1540.scala b/tests/pos/i1540.scala
index 7aa24f459..0fdfea235 100644
--- a/tests/pos/i1540.scala
+++ b/tests/pos/i1540.scala
@@ -1,6 +1,6 @@
class Casey1(val a: Int) {
- def isDefined: Boolean = true
- def isDefined(x: Int): Boolean = ???
+ def isEmpty: Boolean = false
+ def isEmpty(x: Int): Boolean = ???
def get: Int = a
def get(x: Int): String = ???
}
diff --git a/tests/pos/i1540b.scala b/tests/pos/i1540b.scala
index 2b4c5408e..f4408b0c7 100644
--- a/tests/pos/i1540b.scala
+++ b/tests/pos/i1540b.scala
@@ -1,6 +1,6 @@
class Casey1[T](val a: T) {
- def isDefined: Boolean = true
- def isDefined(x: T): Boolean = ???
+ def isEmpty: Boolean = false
+ def isEmpty(x: T): Boolean = ???
def get: T = a
def get(x: T): String = ???
}
diff --git a/tests/pos/i1642.scala b/tests/pos/i1642.scala
new file mode 100644
index 000000000..2fe67cf18
--- /dev/null
+++ b/tests/pos/i1642.scala
@@ -0,0 +1,2 @@
+class Test1(val x: Int) extends AnyVal
+class Test2(val y: Test1) extends AnyVal
diff --git a/tests/pos/i1665.scala b/tests/pos/i1665.scala
new file mode 100644
index 000000000..b7e4a4eed
--- /dev/null
+++ b/tests/pos/i1665.scala
@@ -0,0 +1,7 @@
+
+object Test {
+ !=(1)
+ !=("abc")
+ 1 != this
+ !=(this)
+}
diff --git a/tests/pos/i1704.scala b/tests/pos/i1704.scala
new file mode 100644
index 000000000..94bc03c4d
--- /dev/null
+++ b/tests/pos/i1704.scala
@@ -0,0 +1,4 @@
+trait AnyRef {
+ val StringMatch = new AnyRef {}
+ trait Something { (AnyRef) match { case (StringMatch) => } }
+}
diff --git a/tests/pos/i1737.scala b/tests/pos/i1737.scala
new file mode 100644
index 000000000..e7b428717
--- /dev/null
+++ b/tests/pos/i1737.scala
@@ -0,0 +1,11 @@
+object Test {
+ sealed trait Foo[A]
+ case object FooI extends Foo[Int]
+ case class FooS(b: Boolean) extends Foo[String]
+
+ def algFoo[A](foo: Foo[A]): A =
+ foo match {
+ case FooI => 42
+ case FooS(b) => "foo"
+ }
+}
diff --git a/tests/pos/i1751.scala b/tests/pos/i1751.scala
new file mode 100644
index 000000000..d51cdc65d
--- /dev/null
+++ b/tests/pos/i1751.scala
@@ -0,0 +1,17 @@
+trait Break { protected val break: Int; }
+case class BreakImpl(protected val break: Int) extends Break {}
+object Test {
+ def f2(x: Break) = x match {
+ case BreakImpl(x) => BreakImpl
+ case _ => -1
+ }
+ def f4(x: Any) = x match {
+ case BreakImpl(x) => x
+ case _ => -1
+ }
+ def main(args: Array[String]): Unit = {
+ val break = BreakImpl(22)
+ assert(f2(break) == 22)
+ assert(f4(break) == 22)
+ }
+}
diff --git a/tests/pos/i1753.scala b/tests/pos/i1753.scala
new file mode 100644
index 000000000..e5ad743aa
--- /dev/null
+++ b/tests/pos/i1753.scala
@@ -0,0 +1,22 @@
+abstract class BackendInterface {
+ type Symbol >: Null
+ type ClassDef >: Null
+}
+
+class BTypesFromSymbols[I <: BackendInterface](val int: I) {
+ def isRemote(s: int.Symbol) = println("might've been remote")
+}
+
+trait BCodeIdiomatic {
+ val int: BackendInterface
+ final lazy val bTypes = new BTypesFromSymbols[int.type](int)
+}
+
+trait BCodeSkelBuilder extends BCodeIdiomatic {
+ import int._
+ import bTypes._
+ val b: BTypesFromSymbols[int.type] = bTypes
+ val x: int.type = bTypes.int
+ val y: bTypes.int.type = int
+ def getPlainClass(cd: ClassDef) = bTypes.isRemote(null: Symbol)
+}
diff --git a/tests/pos/i1755.scala b/tests/pos/i1755.scala
new file mode 100644
index 000000000..1361ebeec
--- /dev/null
+++ b/tests/pos/i1755.scala
@@ -0,0 +1,21 @@
+class hierarOverload {
+ trait AB {
+ type TB
+ protected trait A { val entities: List[TB] }
+ protected trait B
+ }
+ object NAnB {
+ type TB = nB
+ type TA = nA
+ class nA { List[nB]() }
+ class nB {}
+ }
+ def foo = { val t = new NAnB.TB() }
+}
+class hierarOverload2 {
+ object NAnB {
+ type TB = nB
+ class nB
+ }
+ def foo = { val t = new NAnB.TB() }
+}
diff --git a/tests/pos/i1756.scala b/tests/pos/i1756.scala
new file mode 100644
index 000000000..e6f6eda60
--- /dev/null
+++ b/tests/pos/i1756.scala
@@ -0,0 +1,20 @@
+class A { { val x = this } }
+class B(x: Int) {
+ class C(x: Int)
+ extends B({
+ val test = this
+ x
+ }) {
+ def this() = {
+ this({
+ 1
+ })
+ }
+ }
+}
+
+// Minimized version
+class D(x: Int) {
+ class E(x: Int) extends D({val test = D.this; x})
+}
+
diff --git a/tests/pos/i1757.scala b/tests/pos/i1757.scala
new file mode 100644
index 000000000..515b4e9bb
--- /dev/null
+++ b/tests/pos/i1757.scala
@@ -0,0 +1,6 @@
+case class B[T](b: List[Int]) {
+ var s: B[Int] = ???
+ def cpy[X](b: List[Int] = b): B[X] = new B[X](b)
+ s.cpy()
+ s.copy()
+}
diff --git a/tests/pos/i1765.scala b/tests/pos/i1765.scala
new file mode 100644
index 000000000..d79129638
--- /dev/null
+++ b/tests/pos/i1765.scala
@@ -0,0 +1,21 @@
+trait T[X]
+
+trait U[X]
+
+trait TC[M[_]] {
+ def foo[M[_]: TC, A](ma: U[A]) = ()
+ implicit val TCofT: TC[T] = new TC[T] {}
+ implicit def any2T[A](a: A): T[A] = new T[A] {}
+ implicit def any2U[A](a: A): U[A] = new U[A] {}
+ val x = foo[T, Int](1)
+ val y = ()
+}
+
+// Minimized version exhibiting an assertion violation in Denotation#current at phase lambdalift:
+trait TC2 {
+// implicit val TCofT: TC2[T] = new TC2[T] {}
+ val TCofT: Object = {
+ class C extends TC2
+ new Object
+ }
+}
diff --git a/tests/pos/i1776.scala b/tests/pos/i1776.scala
new file mode 100644
index 000000000..265ded0d8
--- /dev/null
+++ b/tests/pos/i1776.scala
@@ -0,0 +1,3 @@
+class X(val y: String)
+class Y(y: => String) extends X(y)
+class Z(z: => String) extends X(z)
diff --git a/tests/pos/i1777.scala b/tests/pos/i1777.scala
new file mode 100644
index 000000000..381ff9139
--- /dev/null
+++ b/tests/pos/i1777.scala
@@ -0,0 +1,9 @@
+object Main extends App {
+ import scala.collection.immutable._
+ case class Foo(s: String)
+ {
+ implicit val orderingS: Ordering[String] = Ordering[String] // Crash
+ val tree = TreeMap.empty ++ (1 to 100).map { i => Foo(i.toString) -> i }
+ println(tree.getClass)
+ }
+}
diff --git a/tests/pos/i1786.scala b/tests/pos/i1786.scala
new file mode 100644
index 000000000..3b1d3af52
--- /dev/null
+++ b/tests/pos/i1786.scala
@@ -0,0 +1,18 @@
+package scala
+
+package object meta {
+ def apply(x: Int): Int = x * x
+}
+
+class Test {
+ meta { 5 + 4 }
+
+ scala.meta { 3 }
+
+ scala.meta.`package` { 3 }
+
+ // val m1 = meta // error
+ // val m2 = scala.meta // error
+ val m3 = scala.meta.`package`
+ val m4 = meta.`package`
+}
diff --git a/tests/pos/i1790.scala b/tests/pos/i1790.scala
new file mode 100644
index 000000000..7535255f9
--- /dev/null
+++ b/tests/pos/i1790.scala
@@ -0,0 +1,15 @@
+import scala.util.control.NonFatal
+
+class Try[+T] {
+ def transform[U](s: T => Try[U], f: Throwable => Try[U]): Try[U] =
+ try this match {
+ case Success(v) => s(v)
+ case Failure(e) => f(e)
+ } catch {
+ case NonFatal(e) => Failure(e)
+ }
+}
+final case class Success[+T](value: T) extends Try[T]
+final case class Failure[+T](exception: Throwable) extends Try[T] {
+ def get: T = throw exception
+}
diff --git a/tests/pos/i1793.scala b/tests/pos/i1793.scala
new file mode 100644
index 000000000..fed8a6165
--- /dev/null
+++ b/tests/pos/i1793.scala
@@ -0,0 +1,7 @@
+object Test {
+ import scala.ref.WeakReference
+ def unapply[T <: AnyRef](wr: WeakReference[T]): Option[T] = {
+ val x = wr.underlying.get
+ if (x != null) Some(x) else None
+ }
+}
diff --git a/tests/pos/i1795.scala b/tests/pos/i1795.scala
new file mode 100644
index 000000000..3e8bd1e97
--- /dev/null
+++ b/tests/pos/i1795.scala
@@ -0,0 +1,13 @@
+sealed trait T1 {type M1}
+
+case object o1 extends T1
+
+sealed trait T2 {type M2}
+
+case object o2 extends T2
+
+class TestX {
+ type TestT1 <: T1 {type M1 = TestT2}
+ type TestT2 <: T2 {type M2 = TestT1}
+ //val x: TestT1 = o1
+}
diff --git a/tests/pos/i1797.scala b/tests/pos/i1797.scala
new file mode 100644
index 000000000..1f10082b7
--- /dev/null
+++ b/tests/pos/i1797.scala
@@ -0,0 +1 @@
+case class Tuple1[T](_1: T)
diff --git a/tests/pos/i1803.scala b/tests/pos/i1803.scala
new file mode 100644
index 000000000..19bf21918
--- /dev/null
+++ b/tests/pos/i1803.scala
@@ -0,0 +1,7 @@
+class C[T]
+
+object Test {
+ def f(x: C[Int]) = ???
+
+ f(new C {})
+}
diff --git a/tests/pos/i1812.scala b/tests/pos/i1812.scala
new file mode 100644
index 000000000..653274883
--- /dev/null
+++ b/tests/pos/i1812.scala
@@ -0,0 +1,12 @@
+class FF[R] {
+ def compose(): R = ???
+}
+
+class Test(x: Int) extends AnyVal {
+ def method: Unit = {
+ class Bla
+ class Foo extends FF[Bla] {
+ override def compose() = super[FF].compose()
+ }
+ }
+}
diff --git a/tests/pos/i1812b.scala b/tests/pos/i1812b.scala
new file mode 100644
index 000000000..492c545f1
--- /dev/null
+++ b/tests/pos/i1812b.scala
@@ -0,0 +1,11 @@
+class FF[R] {
+ def compose(): R = ???
+}
+
+class Test(x: Int) extends AnyVal {
+ def method: Unit = {
+ class Bla{ def bar:a.S = ???}
+ trait TRT{ type S}
+ val a: TRT = ???
+ }
+}
diff --git a/tests/pos/i1865.scala b/tests/pos/i1865.scala
new file mode 100644
index 000000000..1b77558ff
--- /dev/null
+++ b/tests/pos/i1865.scala
@@ -0,0 +1,24 @@
+class AbsCell {
+ type T = Node
+ class Node
+}
+
+object Test {
+ def test: Unit = {
+ val cell = new AbsCell
+ new cell.T
+ }
+}
+
+class AbsCell2 {
+ type T = Node
+ val value: T = value
+ def set(x: T): Unit = {}
+ class Node
+}
+object init {
+ def main = {
+ val cell = new AbsCell2 { val init = new Node }
+ cell set (new cell.T)
+ }
+}
diff --git a/tests/pos/i1867.scala b/tests/pos/i1867.scala
new file mode 100644
index 000000000..b6377c4f0
--- /dev/null
+++ b/tests/pos/i1867.scala
@@ -0,0 +1,3 @@
+trait B {
+ def f1: {}
+}
diff --git a/tests/pos/i1868.scala b/tests/pos/i1868.scala
new file mode 100644
index 000000000..3ca3e0094
--- /dev/null
+++ b/tests/pos/i1868.scala
@@ -0,0 +1,7 @@
+class Test[X](x: X) {
+ def checkSpecialization[Y](y: Y): X = {
+ def specMe[@specialized T]() = ()
+ x
+ }
+ private def checkNameStartsWith(prefix: String) = { (new Exception) }
+}
diff --git a/tests/pos/i1891.scala b/tests/pos/i1891.scala
new file mode 100644
index 000000000..b178c256b
--- /dev/null
+++ b/tests/pos/i1891.scala
@@ -0,0 +1,11 @@
+object Test {
+ class CC2[A, B](a: A, b: B)
+
+ type T2[A, B] = CC2[A, B]
+
+ class ArrowAssoc[A](val self: A) {
+ @inline def f[B](y: B): CC2[A, B] = new CC2(self, y)
+ }
+
+ def foo = (new ArrowAssoc(1)).f(2)
+}
diff --git a/tests/pos/implicits.scala b/tests/pos/implicits.scala
index 1a3e0b4da..feb48771f 100644
--- a/tests/pos/implicits.scala
+++ b/tests/pos/implicits.scala
@@ -6,4 +6,9 @@ object Test {
val x: X = Byte.MinValue
+ def foo() = {
+ implicit val x = "abc"
+ implicitly[String]
+ }
+
}
diff --git a/tests/pos/lazyValsSepComp.scala b/tests/pos/lazyValsSepComp.scala
index 1a7e37020..048231eb0 100644
--- a/tests/pos/lazyValsSepComp.scala
+++ b/tests/pos/lazyValsSepComp.scala
@@ -12,5 +12,5 @@ import dotty.tools.dotc.core.Contexts._
object Foo {
val definitions: Definitions = null
def defn = definitions
- def go = defn.FunctionType(0)
+ def go = defn.FunctionClassPerRun
}
diff --git a/tests/pos/pos_valueclasses/optmatch.scala b/tests/pos/pos_valueclasses/optmatch.scala
index a7995a455..ff1a17906 100644
--- a/tests/pos/pos_valueclasses/optmatch.scala
+++ b/tests/pos/pos_valueclasses/optmatch.scala
@@ -7,7 +7,7 @@ package optmatch
class NonZeroLong(val value: Long) extends AnyVal {
def get: Long = value
- def isDefined: Boolean = get != 0l
+ def isEmpty: Boolean = get == 0l
}
object NonZeroLong {
def unapply(value: Long): NonZeroLong = new NonZeroLong(value)
diff --git a/tests/repl/def.check b/tests/repl/def.check
new file mode 100644
index 000000000..9d6538354
--- /dev/null
+++ b/tests/repl/def.check
@@ -0,0 +1,13 @@
+scala> def foo = 5
+def foo: Int
+scala> def bar: String = "1"
+def bar: String
+scala> def baz() = 2
+def baz(): Int
+scala> def qux(): Int = 2
+def qux(): Int
+scala> def id(x: 4): 4 = x
+def id(x: 4.type): Int(4)
+scala> id(4)
+val res0: Int = 4
+scala> :quit
diff --git a/tests/repl/import.check b/tests/repl/import.check
index ccaa52190..d53906ddc 100644
--- a/tests/repl/import.check
+++ b/tests/repl/import.check
@@ -1,11 +1,11 @@
scala> import collection.mutable._
import collection.mutable._
scala> val buf = new ListBuffer[Int]
-buf: scala.collection.mutable.ListBuffer[Int] = ListBuffer()
+val buf: scala.collection.mutable.ListBuffer[Int] = ListBuffer()
scala> buf += 22
-res0: scala.collection.mutable.ListBuffer[Int] = ListBuffer(22)
+val res0: scala.collection.mutable.ListBuffer[Int] = ListBuffer(22)
scala> buf ++= List(1, 2, 3)
-res1: scala.collection.mutable.ListBuffer[Int] = ListBuffer(22, 1, 2, 3)
+val res1: scala.collection.mutable.ListBuffer[Int] = ListBuffer(22, 1, 2, 3)
scala> buf.toList
-res2: scala.collection.immutable.List[Int] = List(22, 1, 2, 3)
+val res2: List[Int] = List(22, 1, 2, 3)
scala> :quit
diff --git a/tests/repl/imports.check b/tests/repl/imports.check
index 7e078fe00..5260589a9 100644
--- a/tests/repl/imports.check
+++ b/tests/repl/imports.check
@@ -1,7 +1,7 @@
scala> import scala.collection.mutable
import scala.collection.mutable
scala> val buf = mutable.ListBuffer[Int]()
-buf: scala.collection.mutable.ListBuffer[Int] = ListBuffer()
+val buf: scala.collection.mutable.ListBuffer[Int] = ListBuffer()
scala> object o { val xs = List(1, 2, 3) }
defined module o
scala> import o._
@@ -14,7 +14,7 @@ scala> buf += xs
| required: String
|
scala> buf ++= xs
-res1: scala.collection.mutable.ListBuffer[Int] = ListBuffer(1, 2, 3)
+val res1: scala.collection.mutable.ListBuffer[Int] = ListBuffer(1, 2, 3)
scala> import util.foo
-- Error: <console> ------------------------------------------------------------
8 |import util.foo
diff --git a/tests/repl/innerClasses.check b/tests/repl/innerClasses.check
new file mode 100644
index 000000000..72dc6ae45
--- /dev/null
+++ b/tests/repl/innerClasses.check
@@ -0,0 +1,5 @@
+scala> class A { class Inner }
+defined class A
+scala> class B extends A { class Inner2 extends super.Inner }
+defined class B
+scala> :quit
diff --git a/tests/repl/onePlusOne.check b/tests/repl/onePlusOne.check
index 9db6e6817..1e9060693 100644
--- a/tests/repl/onePlusOne.check
+++ b/tests/repl/onePlusOne.check
@@ -1,3 +1,3 @@
scala> 1+1
-res0: Int = 2
+val res0: Int = 2
scala> :quit
diff --git a/tests/repl/patdef.check b/tests/repl/patdef.check
index 0cb1c6d4f..c92b678e0 100644
--- a/tests/repl/patdef.check
+++ b/tests/repl/patdef.check
@@ -1,10 +1,10 @@
-scala> val Const,x = 0
-Const: Int = 0
-x: Int = 0
+scala> val Const, x = 0
+val Const: Int = 0
+val x: Int = 0
scala> val (Const, List(`x`, _, a), b) = (0, List(0, 1337, 1), 2)
-a: Int = 1
-b: Int = 2
+val a: Int = 1
+val b: Int = 2
scala> val a@b = 0
-a: Int @unchecked = 0
-b: Int @unchecked = 0
+val a: Int @unchecked = 0
+val b: Int @unchecked = 0
scala> :quit
diff --git a/tests/repl/toplevelTry.check b/tests/repl/toplevelTry.check
index 9d2c87b35..5b9be157f 100644
--- a/tests/repl/toplevelTry.check
+++ b/tests/repl/toplevelTry.check
@@ -1,3 +1,3 @@
scala> try { 0 } catch { _: Throwable => 1 }
-res0: Int = 0
+val res0: Int = 0
scala> :quit
diff --git a/tests/repl/vars.check b/tests/repl/vars.check
index 5cebbf61c..2e21e1a9f 100644
--- a/tests/repl/vars.check
+++ b/tests/repl/vars.check
@@ -1,8 +1,8 @@
scala> var x = 0
-x: Int = 0
+var x: Int = 0
scala> x = x + 1
x: Int = 1
scala> x *= 2
scala> x
-res2: Int = 2
+val res2: Int = 2
scala> :quit
diff --git a/tests/run/final-var.check b/tests/run/final-var.check
new file mode 100644
index 000000000..7565230c0
--- /dev/null
+++ b/tests/run/final-var.check
@@ -0,0 +1,4 @@
+false
+true
+false
+true
diff --git a/tests/run/final-var.scala b/tests/run/final-var.scala
new file mode 100644
index 000000000..94a6c453c
--- /dev/null
+++ b/tests/run/final-var.scala
@@ -0,0 +1,20 @@
+object Test {
+ def main(args: Array[String]): Unit = {
+ println(Obj.myFinalVar)
+ Obj.myFinalVar = true
+ println(Obj.myFinalVar)
+
+ val o = new Cls
+ println(o.myFinalVar)
+ o.myFinalVar = true
+ println(o.myFinalVar)
+ }
+}
+
+object Obj {
+ final var myFinalVar: Boolean = false
+}
+
+class Cls {
+ final var myFinalVar: Boolean = false
+}
diff --git a/tests/run/i1732.scala b/tests/run/i1732.scala
new file mode 100644
index 000000000..6c090a2eb
--- /dev/null
+++ b/tests/run/i1732.scala
@@ -0,0 +1,15 @@
+object Test {
+ import scala.util.control.Breaks
+
+ def brk(f: () => Unit): Unit = try {
+ f()
+ } catch {
+ case ex: NotImplementedError =>
+ }
+ def main(args: Array[String]): Unit = {
+ brk { () => ??? }
+ Breaks.breakable {
+ Breaks.break
+ }
+ }
+}
diff --git a/tests/run/i1748.check b/tests/run/i1748.check
new file mode 100644
index 000000000..888299747
--- /dev/null
+++ b/tests/run/i1748.check
@@ -0,0 +1,2 @@
+class
+ extends
diff --git a/tests/run/i1748.scala b/tests/run/i1748.scala
new file mode 100644
index 000000000..bb3df1336
--- /dev/null
+++ b/tests/run/i1748.scala
@@ -0,0 +1,14 @@
+object Test {
+ implicit class Foo(sc: StringContext) {
+ object q {
+ def unapply(arg: Any): Option[(Any, Any)] =
+ Some((sc.parts(0), sc.parts(1)))
+ }
+ }
+
+ def main(args: Array[String]): Unit = {
+ val q"class $name extends $parent" = new Object
+ println(name)
+ println(parent)
+ }
+} \ No newline at end of file
diff --git a/tests/run/i1773.check b/tests/run/i1773.check
new file mode 100644
index 000000000..888299747
--- /dev/null
+++ b/tests/run/i1773.check
@@ -0,0 +1,2 @@
+class
+ extends
diff --git a/tests/run/i1773.scala b/tests/run/i1773.scala
new file mode 100644
index 000000000..82fa0dfb4
--- /dev/null
+++ b/tests/run/i1773.scala
@@ -0,0 +1,14 @@
+object Test {
+ implicit class Foo(sc: StringContext) {
+ object q {
+ def unapply(arg: Any): Option[(Any, Any)] =
+ Some((sc.parts(0), sc.parts(1)))
+ }
+ }
+
+ def main(args: Array[String]): Unit = {
+ val q"class ${name: String} extends ${parent: String}" = new Object
+ println(name)
+ println(parent)
+ }
+}
diff --git a/tests/run/i1779.check b/tests/run/i1779.check
new file mode 100644
index 000000000..4ef6e900e
--- /dev/null
+++ b/tests/run/i1779.check
@@ -0,0 +1 @@
+ extends
diff --git a/tests/run/i1779.scala b/tests/run/i1779.scala
new file mode 100644
index 000000000..e81bc97b6
--- /dev/null
+++ b/tests/run/i1779.scala
@@ -0,0 +1,13 @@
+object Test {
+ implicit class Foo(sc: StringContext) {
+ object q {
+ def unapply(arg: Any): Option[(Any, Any)] =
+ Some((sc.parts(0), sc.parts(1)))
+ }
+ }
+
+ def main(args: Array[String]): Unit = {
+ val q"class $_ extends $_parent" = new Object
+ println(_parent)
+ }
+}
diff --git a/tests/run/i1820.check b/tests/run/i1820.check
new file mode 100644
index 000000000..789819226
--- /dev/null
+++ b/tests/run/i1820.check
@@ -0,0 +1 @@
+a
diff --git a/tests/run/i1820.scala b/tests/run/i1820.scala
new file mode 100644
index 000000000..b39e6d108
--- /dev/null
+++ b/tests/run/i1820.scala
@@ -0,0 +1,17 @@
+class A {
+ val a = "a"
+ trait Inner {
+ def f = println(a)
+ def h = 3
+ }
+}
+
+class Inner extends Test.a.Inner
+
+object Test {
+ val a = new A
+
+ def main(args: Array[String]): Unit = {
+ (new Inner).f
+ }
+}
diff --git a/tests/run/i1820b.check b/tests/run/i1820b.check
new file mode 100644
index 000000000..789819226
--- /dev/null
+++ b/tests/run/i1820b.check
@@ -0,0 +1 @@
+a
diff --git a/tests/run/i1820b.scala b/tests/run/i1820b.scala
new file mode 100644
index 000000000..3452b6158
--- /dev/null
+++ b/tests/run/i1820b.scala
@@ -0,0 +1,19 @@
+trait A {
+ val a = "a"
+ trait Inner {
+ def f = println(a)
+ def h = 3
+ }
+}
+
+trait B extends A {
+ trait Inner2 extends Inner
+ def g = new Inner2 {}
+}
+
+object Test {
+ def main(args: Array[String]): Unit = {
+ val b = new B {}
+ b.g.f
+ }
+}
diff --git a/tests/run/implicitFuns.scala b/tests/run/implicitFuns.scala
new file mode 100644
index 000000000..496fba0d3
--- /dev/null
+++ b/tests/run/implicitFuns.scala
@@ -0,0 +1,261 @@
+object Test {
+ def main(args: Array[String]): Unit = {
+
+ implicit val world: String = "world!"
+
+ val i1 = (implicit (s: String) => s.length > 2)
+ val i2 = {implicit (s: String) => s.length > 2}
+
+ assert(i1)
+ assert(i2)
+
+ val x: implicit String => Boolean = { implicit (s: String) => s.length > 2 }
+
+ val xx: implicit (String, Int) => Int = implicit (x: String, y: Int) => x.length + y
+
+ val y: String => Boolean = x
+
+ object nested {
+ implicit val empty: String = ""
+ assert(!x)
+ }
+
+ val yy: (String, Int) => Any = xx
+
+ val z1: implicit String => Boolean = implicitly[String].length >= 2
+ assert(z1)
+
+ type StringlyBool = implicit String => Boolean
+
+ val z2: StringlyBool = implicitly[String].length >= 2
+ assert(z2)
+
+ type Stringly[T] = implicit String => T
+
+ val z3: Stringly[Boolean] = implicitly[String].length >= 2
+ assert(z3)
+
+ type GenericImplicit[X] = implicit X => Boolean
+
+ val z4: GenericImplicit[String] = implicitly[String].length >= 2
+ assert(z4)
+
+ val b = x("hello")
+
+ val b1: Boolean = b
+
+ val bi = x
+
+ val bi1: Boolean = bi
+
+ val c = xx("hh", 22)
+
+ val c1: Int = c
+
+ Contextual.main(args)
+
+ def foo(s: String): Stringly[Int] = 42
+
+ (if ("".isEmpty) foo("") else foo("")).apply("")
+ }
+}
+
+object Contextual {
+
+ class Key[+V]
+
+ class Context(bindings: Map[Key[Any], Any]) {
+ def binding[V](key: Key[V]): Option[V] =
+ bindings.get(key).asInstanceOf[Option[V]]
+ def withBinding[V](key: Key[V], value: V): Context =
+ new Context(bindings + ((key, value)))
+ }
+
+ val rootContext = new Context(Map())
+
+ val Source = new Key[String]
+ val Options = new Key[List[String]]
+
+ type Ctx[T] = implicit Context => T
+
+ def ctx: Ctx[Context] = implicitly[Context]
+
+ def compile(s: String): Ctx[Boolean] =
+ runOn(new java.io.File(s))(ctx.withBinding(Source, s)) >= 0
+
+ def runOn(f: java.io.File): Ctx[Int] = {
+ val options = List("-verbose", "-explaintypes")
+ process(f).apply(ctx.withBinding(Options, options))
+ }
+
+ def process(f: java.io.File): Ctx[Int] =
+ ctx.binding(Source).get.length - ctx.binding(Options).get.length
+
+ def main(args: Array[String]) = {
+ implicit val context: Context = rootContext
+ assert(compile("abc"))
+ assert(compile("ab"))
+ assert(!compile("a"))
+ }
+}
+
+import collection.mutable.ListBuffer
+
+class Transaction {
+ private val log = new ListBuffer[String]
+ def println(s: String): Unit = log += s
+
+ private var aborted = false
+ private var committed = false
+
+ def abort(): Unit = { aborted = true }
+ def isAborted = aborted
+
+ def commit(): Unit =
+ if (!aborted && !committed) {
+ Console.println("******* log ********")
+ log.foreach(Console.println)
+ committed = true
+ }
+}
+
+object TransactionalExplicit {
+
+ def transaction[T](op: Transaction => T) = {
+ val trans: Transaction = new Transaction
+ op(trans)
+ trans.commit()
+ }
+
+ def f1(x: Int)(implicit thisTransaction: Transaction): Int = {
+ thisTransaction.println(s"first step: $x")
+ f2(x + 1)
+ }
+ def f2(x: Int)(implicit thisTransaction: Transaction): Int = {
+ thisTransaction.println(s"second step: $x")
+ f3(x * x)
+ }
+ def f3(x: Int)(implicit thisTransaction: Transaction): Int = {
+ thisTransaction.println(s"third step: $x")
+ if (x % 2 != 0) thisTransaction.abort()
+ x
+ }
+
+ def main(args: Array[String]) = {
+ transaction {
+ implicit thisTransaction =>
+ val res = f1(args.length)
+ println(if (thisTransaction.isAborted) "aborted" else s"result: $res")
+ }
+ }
+}
+
+object Transactional {
+ type Transactional[T] = implicit Transaction => T
+
+ def transaction[T](op: Transactional[T]) = {
+ implicit val trans: Transaction = new Transaction
+ op
+ trans.commit()
+ }
+
+ def thisTransaction: Transactional[Transaction] = implicitly[Transaction]
+
+ def f1(x: Int): Transactional[Int] = {
+ thisTransaction.println(s"first step: $x")
+ f2(x + 1)
+ }
+ def f2(x: Int): Transactional[Int] = {
+ thisTransaction.println(s"second step: $x")
+ f3(x * x)
+ }
+ def f3(x: Int): Transactional[Int] = {
+ thisTransaction.println(s"third step: $x")
+ if (x % 2 != 0) thisTransaction.abort()
+ x
+ }
+
+ def main(args: Array[String]) = {
+ transaction {
+ val res = f1(args.length)
+ println(if (thisTransaction.isAborted) "aborted" else s"result: $res")
+ }
+ }
+}
+
+object TransactionalExpansion {
+
+ def transaction[T](op: Transaction => T) = {
+ val trans: Transaction = new Transaction
+ op.apply(trans)
+ trans.commit()
+ }
+
+ def thisTransaction = $t: Transaction => $t
+
+ def f1(x: Int) = { $t: Transaction =>
+ thisTransaction.apply($t).println(s"first step: $x")
+ f2(x + 1).apply($t)
+ }
+ def f2(x: Int) = { $t: Transaction =>
+ thisTransaction.apply($t).println(s"second step: $x")
+ f3(x * x).apply($t)
+ }
+ def f3(x: Int) = { $t: Transaction =>
+ thisTransaction.apply($t).println(s"third step: $x")
+ if (x % 2 != 0) thisTransaction.apply($t).abort()
+ x
+ }
+
+ def main(args: Array[String]) = {
+ transaction { $t =>
+ val res = f1(args.length).apply($t)
+ println(if (thisTransaction.apply($t).isAborted) "aborted" else s"result: $res")
+ }
+ }
+}
+
+object TransactionalAbstracted {
+ type Transactional[T] = implicit Transaction => T
+
+ trait TransOps {
+ def thisTransaction: Transactional[Transaction]
+ def f1(x: Int): Transactional[Int]
+ def f2(x: Int): Transactional[Int]
+ def f3(x: Int): Transactional[Int]
+ }
+
+ object TransOpsObj extends TransOps {
+
+ def thisTransaction: Transactional[Transaction] = implicitly[Transaction]
+
+ def f1(x: Int): Transactional[Int] = {
+ thisTransaction.println(s"first step: $x")
+ f2(x + 1)
+ }
+ def f2(x: Int): Transactional[Int] = {
+ thisTransaction.println(s"second step: $x")
+ f3(x * x)
+ }
+ def f3(x: Int): Transactional[Int] = {
+ thisTransaction.println(s"third step: $x")
+ if (x % 2 != 0) thisTransaction.abort()
+ x
+ }
+ }
+
+ val transOps: TransOps = TransOpsObj
+
+ def transaction[T](op: Transactional[T]) = {
+ implicit val trans: Transaction = new Transaction
+ op
+ trans.commit()
+ }
+
+ def main(args: Array[String]) = {
+ transaction {
+ val res = transOps.f1(args.length)
+ println(if (transOps.thisTransaction.isAborted) "aborted" else s"result: $res")
+ }
+ }
+}