Skip to content

Commit 6ff1edd

Browse files
committed
Merge branch 'main' into parametricity-for-safe-init-enums
2 parents da09d3a + 8c404b1 commit 6ff1edd

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+2460
-87
lines changed

.github/workflows/ci.yaml

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -115,10 +115,6 @@ jobs:
115115
./project/scripts/cmdTests
116116
./project/scripts/bootstrappedOnlyCmdTests
117117
118-
- name: MiMa
119-
run: |
120-
./project/scripts/sbt ";scala3-interfaces/mimaReportBinaryIssues ;scala3-library-bootstrapped/mimaReportBinaryIssues ;scala3-library-bootstrappedJS/mimaReportBinaryIssues; tasty-core-bootstrapped/mimaReportBinaryIssues"
121-
122118
test_windows_fast:
123119
runs-on: [self-hosted, Windows]
124120
if: "(
@@ -189,6 +185,47 @@ jobs:
189185
run: sbt ";sjsJUnitTests/test ;sjsCompilerTests/test"
190186
shell: cmd
191187

188+
mima:
189+
name: MiMa
190+
runs-on: [self-hosted, Linux]
191+
container:
192+
image: lampepfl/dotty:2021-03-22
193+
options: --cpu-shares 4096
194+
volumes:
195+
- ${{ github.workspace }}/../../cache/sbt:/root/.sbt
196+
- ${{ github.workspace }}/../../cache/ivy:/root/.ivy2/cache
197+
- ${{ github.workspace }}/../../cache/general:/root/.cache
198+
if: "github.event_name == 'schedule' && github.repository == 'lampepfl/dotty'
199+
|| github.event_name == 'push'
200+
|| (
201+
github.event_name == 'pull_request'
202+
&& !contains(github.event.pull_request.body, '[skip ci]')
203+
&& !contains(github.event.pull_request.body, '[skip mima]')
204+
)
205+
|| (
206+
github.event_name == 'workflow_dispatch'
207+
&& github.repository == 'lampepfl/dotty'
208+
)"
209+
steps:
210+
- name: Reset existing repo
211+
run: git -c "http.https://github.com/.extraheader=" fetch --recurse-submodules=no "https://github.com/lampepfl/dotty" && git reset --hard FETCH_HEAD || true
212+
213+
- name: Checkout cleanup script
214+
uses: actions/checkout@v2
215+
216+
- name: Cleanup
217+
run: .github/workflows/cleanup.sh
218+
219+
- name: Git Checkout
220+
uses: actions/checkout@v2
221+
222+
- name: Add SBT proxy repositories
223+
run: cp -vf .github/workflows/repositories /root/.sbt/ ; true
224+
225+
- name: MiMa
226+
run: |
227+
./project/scripts/sbt ";scala3-interfaces/mimaReportBinaryIssues ;scala3-library-bootstrapped/mimaReportBinaryIssues ;scala3-library-bootstrappedJS/mimaReportBinaryIssues; tasty-core-bootstrapped/mimaReportBinaryIssues"
228+
192229
community_build_a:
193230
runs-on: [self-hosted, Linux]
194231
container:
@@ -472,7 +509,7 @@ jobs:
472509
- ${{ github.workspace }}/../../cache/sbt:/root/.sbt
473510
- ${{ github.workspace }}/../../cache/ivy:/root/.ivy2/cache
474511
- ${{ github.workspace }}/../../cache/general:/root/.cache
475-
needs: [test_non_bootstrapped, test, community_build_a, community_build_b, community_build_c, community_build_forward_compat, test_sbt, test_java8]
512+
needs: [test_non_bootstrapped, test, mima, community_build_a, community_build_b, community_build_c, community_build_forward_compat, test_sbt, test_java8]
476513
if: "(github.event_name == 'schedule' || github.event_name == 'workflow_dispatch') && github.repository == 'lampepfl/dotty'"
477514
env:
478515
NIGHTLYBUILD: yes
@@ -573,7 +610,7 @@ jobs:
573610
- ${{ github.workspace }}/../../cache/sbt:/root/.sbt
574611
- ${{ github.workspace }}/../../cache/ivy:/root/.ivy2/cache
575612
- ${{ github.workspace }}/../../cache/general:/root/.cache
576-
needs: [test_non_bootstrapped, test, community_build_a, community_build_b, community_build_c, test_sbt, test_java8]
613+
needs: [test_non_bootstrapped, test, mima, community_build_a, community_build_b, community_build_c, test_sbt, test_java8]
577614
if: "github.event_name == 'push'
578615
&& startsWith(github.event.ref, 'refs/tags/')"
579616

.github/workflows/scaladoc.yaml

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,15 @@ jobs:
5252
- name: Generate testcases documentation
5353
run: ./project/scripts/sbt scaladoc/generateTestcasesDocumentation
5454

55-
- name: Generate reference documentation
56-
run: ./project/scripts/sbt scaladoc/generateReferenceDocumentation
55+
- name: Generate reference documentation and check links stability
56+
run: |
57+
./project/scripts/sbt scaladoc/generateReferenceDocumentation
58+
./project/scripts/docsLinksStability ./scaladoc/output/reference ./project/scripts/expected-links/reference-expected-links.txt
5759
58-
- name: Generate Scala 3 documentation
59-
run: ./project/scripts/sbt scaladoc/generateScalaDocumentation
60+
- name: Generate Scala 3 documentation and check links stability
61+
run: |
62+
./project/scripts/sbt scaladoc/generateScalaDocumentation
63+
./project/scripts/docsLinksStability ./scaladoc/output/scala3 ./project/scripts/expected-links/scala3-expected-links.txt
6064
6165
- name: Generate documentation for example project using dotty-sbt
6266
run: ./project/scripts/sbt "sbt-test/scripted sbt-dotty/scaladoc"

compiler/src/dotty/tools/dotc/reporting/Reporter.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ abstract class Reporter extends interfaces.ReporterResult {
153153
case w: Warning if ctx.settings.XfatalWarnings.value => w.toError
154154
case _ => dia
155155
if !isHidden(d) then // avoid isHidden test for summarized warnings so that message is not forced
156+
markReported(d)
156157
withMode(Mode.Printing)(doReport(d))
157158
d match {
158159
case _: Warning => _warningCount += 1
@@ -236,6 +237,8 @@ abstract class Reporter extends interfaces.ReporterResult {
236237
def isHidden(dia: Diagnostic)(using Context): Boolean =
237238
ctx.mode.is(Mode.Printing)
238239

240+
def markReported(dia: Diagnostic)(using Context): Unit = ()
241+
239242
/** Does this reporter contain errors that have yet to be reported by its outer reporter ?
240243
* Note: this is always false when there is no outer reporter.
241244
*/

compiler/src/dotty/tools/dotc/reporting/UniqueMessagePositions.scala

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,24 +12,27 @@ trait UniqueMessagePositions extends Reporter {
1212

1313
private val positions = new mutable.HashMap[(SourceFile, Integer), Diagnostic]
1414

15+
extension (dia1: Diagnostic)
16+
private def hides(dia2: Diagnostic)(using Context): Boolean =
17+
if dia2.msg.showAlways then dia1.msg.getClass == dia2.msg.getClass
18+
else dia1.level >= dia2.level
19+
1520
/** Logs a position and returns true if it was already logged.
1621
* @note Two positions are considered identical for logging if they have the same point.
1722
*/
1823
override def isHidden(dia: Diagnostic)(using Context): Boolean =
19-
extension (dia1: Diagnostic) def hides(dia2: Diagnostic): Boolean =
20-
if dia2.msg.showAlways then dia1.msg.getClass == dia2.msg.getClass
21-
else dia1.level >= dia2.level
22-
super.isHidden(dia) || {
24+
super.isHidden(dia)
25+
||
2326
dia.pos.exists
2427
&& !ctx.settings.YshowSuppressedErrors.value
25-
&& {
26-
var shouldHide = false
27-
for (pos <- dia.pos.start to dia.pos.end)
28-
positions get (ctx.source, pos) match {
29-
case Some(dia1) if dia1.hides(dia) => shouldHide = true
30-
case _ => positions((ctx.source, pos)) = dia
31-
}
32-
shouldHide
33-
}
34-
}
28+
&& (dia.pos.start to dia.pos.end).exists(pos =>
29+
positions.get((ctx.source, pos)).exists(_.hides(dia)))
30+
31+
override def markReported(dia: Diagnostic)(using Context): Unit =
32+
if dia.pos.exists then
33+
for (pos <- dia.pos.start to dia.pos.end)
34+
positions.get(ctx.source, pos) match
35+
case Some(dia1) if dia1.hides(dia) =>
36+
case _ => positions((ctx.source, pos)) = dia
37+
super.markReported(dia)
3538
}

compiler/src/dotty/tools/dotc/transform/init/Errors.scala

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ package init
55

66
import ast.tpd._
77
import core._
8+
import util.SourcePosition
89
import Decorators._, printing.SyntaxHighlighting
910
import Types._, Symbols._, Contexts._
1011

@@ -26,28 +27,44 @@ object Errors {
2627
def toErrors: Errors = this :: Nil
2728

2829
def stacktrace(using Context): String = if (trace.isEmpty) "" else " Calling trace:\n" + {
29-
var indentCount = 0
3030
var last: String = ""
3131
val sb = new StringBuilder
3232
trace.foreach { tree =>
33-
indentCount += 1
3433
val pos = tree.sourcePos
35-
val prefix = s"${ " " * indentCount }-> "
34+
val prefix = "-> "
3635
val line =
3736
if pos.source.exists then
3837
val loc = "[ " + pos.source.file.name + ":" + (pos.line + 1) + " ]"
3938
val code = SyntaxHighlighting.highlight(pos.lineContent.trim.nn)
4039
i"$code\t$loc"
4140
else
4241
tree.show
42+
val positionMarkerLine =
43+
if pos.exists && pos.source.exists then
44+
positionMarker(pos)
45+
else ""
4346

44-
if (last != line) sb.append(prefix + line + "\n")
47+
if (last != line) sb.append(prefix + line + "\n" + positionMarkerLine )
4548

4649
last = line
4750
}
4851
sb.toString
4952
}
5053

54+
/** Used to underline source positions in the stack trace
55+
* pos.source must exist
56+
*/
57+
private def positionMarker(pos: SourcePosition): String = {
58+
val trimmed = pos.lineContent.takeWhile(c => c.isWhitespace).length
59+
val padding = pos.startColumnPadding.substring(trimmed).nn + " "
60+
val carets =
61+
if (pos.startLine == pos.endLine)
62+
"^" * math.max(1, pos.endColumn - pos.startColumn)
63+
else "^"
64+
65+
s"$padding$carets\n"
66+
}
67+
5168
/** Flatten UnsafePromotion errors
5269
*/
5370
def flatten: Errors = this match {

compiler/src/dotty/tools/dotc/typer/Inliner.scala

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,11 @@ object Inliner {
4040

4141
private type DefBuffer = mutable.ListBuffer[ValOrDefDef]
4242

43+
/** An exception signalling that an inline info cannot be computed due to a
44+
* cyclic reference. i14772.scala shows a case where this happens.
45+
*/
46+
private[typer] class MissingInlineInfo extends Exception
47+
4348
/** `sym` is an inline method with a known body to inline.
4449
*/
4550
def hasBodyToInline(sym: SymDenotation)(using Context): Boolean =
@@ -154,7 +159,10 @@ object Inliner {
154159
if bindings.nonEmpty then
155160
cpy.Block(tree)(bindings.toList, inlineCall(tree1))
156161
else if enclosingInlineds.length < ctx.settings.XmaxInlines.value && !reachedInlinedTreesLimit then
157-
val body = bodyToInline(tree.symbol) // can typecheck the tree and thereby produce errors
162+
val body =
163+
try bodyToInline(tree.symbol) // can typecheck the tree and thereby produce errors
164+
catch case _: MissingInlineInfo =>
165+
throw CyclicReference(ctx.owner)
158166
new Inliner(tree, body).inlined(tree.srcPos)
159167
else
160168
ctx.base.stopInlining = true

compiler/src/dotty/tools/dotc/typer/Namer.scala

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,10 @@ class Namer { typer: Typer =>
103103
}
104104
}
105105

106+
def hasDefinedSymbol(tree: Tree)(using Context): Boolean =
107+
val xtree = expanded(tree)
108+
xtree.hasAttachment(TypedAhead) || xtree.hasAttachment(SymOfTree)
109+
106110
/** The enclosing class with given name; error if none exists */
107111
def enclosingClassNamed(name: TypeName, span: Span)(using Context): Symbol =
108112
if (name.isEmpty) NoSymbol
@@ -837,6 +841,10 @@ class Namer { typer: Typer =>
837841
private def addInlineInfo(sym: Symbol) = original match {
838842
case original: untpd.DefDef if sym.isInlineMethod =>
839843
def rhsToInline(using Context): tpd.Tree =
844+
if !original.symbol.exists && !hasDefinedSymbol(original) then
845+
throw
846+
if sym.isCompleted then Inliner.MissingInlineInfo()
847+
else CyclicReference(sym)
840848
val mdef = typedAheadExpr(original).asInstanceOf[tpd.DefDef]
841849
PrepareInlineable.wrapRHS(original, mdef.tpt, mdef.rhs)
842850
PrepareInlineable.registerInlineInfo(sym, rhsToInline)(using localContext(sym))

compiler/src/dotty/tools/dotc/typer/Typer.scala

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3539,14 +3539,10 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
35393539
val namedArgs = wtp.paramNames.lazyZip(args).flatMap { (pname, arg) =>
35403540
if (arg.tpe.isError) Nil else untpd.NamedArg(pname, untpd.TypedSplice(arg)) :: Nil
35413541
}
3542-
tryEither {
3543-
val app = cpy.Apply(tree)(untpd.TypedSplice(tree), namedArgs)
3544-
if (wtp.isContextualMethod) app.setApplyKind(ApplyKind.Using)
3545-
typr.println(i"try with default implicit args $app")
3546-
typed(app, pt, locked)
3547-
} { (_, _) =>
3548-
issueErrors()
3549-
}
3542+
val app = cpy.Apply(tree)(untpd.TypedSplice(tree), namedArgs)
3543+
if (wtp.isContextualMethod) app.setApplyKind(ApplyKind.Using)
3544+
typr.println(i"try with default implicit args $app")
3545+
typed(app, pt, locked)
35503546
else issueErrors()
35513547
}
35523548
else tree match {

compiler/src/dotty/tools/dotc/util/SourceFile.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ class SourceFile(val file: AbstractFile, computeContent: => Array[Char]) extends
212212
var idx = startOfLine(offset)
213213
val pad = new StringBuilder
214214
while (idx != offset) {
215-
pad.append(if (idx < length && content()(idx) == '\t') '\t' else ' ')
215+
pad.append(if (idx < content().length && content()(idx) == '\t') '\t' else ' ')
216216
idx += 1
217217
}
218218
pad.result()

project/scripts/docsLinksStability

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#!/usr/bin/env bash
2+
set -u
3+
4+
echo "Testing links stability in documentation"
5+
6+
DOCS_DIR=$1 # The location of documentation is passed as a first parameter
7+
8+
EXPECTED_LINKS_FILE=$2 # The location of expected-links.txt is passed as a second parameter
9+
10+
pushd $DOCS_DIR > /dev/null # Go to docs dir but remember previous location
11+
# We need to go to docs dir to make find return correct relative paths
12+
find . -type f -name "*.html" | sort | (popd > /dev/null; diff $EXPECTED_LINKS_FILE -;)
13+
# We list every html file in documentation, then sort it and finally compare to the expected links list.
14+
# Before running diff we need to popd to return to the previous location because we don't have relative path to the expected links file.
15+
16+
if [ ! $? -eq 0 ]
17+
then
18+
echo "Links changed. If it's intentional, regenerate expected links list by running ./project/scripts/regenerateExpectedLinks $1 $2"
19+
exit -1
20+
else
21+
echo "Links OK!"
22+
exit 0
23+
fi

0 commit comments

Comments
 (0)