Skip to content

Commit 49cb71a

Browse files
Merge branch 'main' into ci/release-include-msi
2 parents f47e2b0 + 11c957c commit 49cb71a

File tree

97 files changed

+4489
-428
lines changed

Some content is hidden

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

97 files changed

+4489
-428
lines changed

.github/workflows/build-msi.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ on:
1414
workflow_call:
1515

1616
env:
17-
# NECESSARY FLAG TO CORRECTLY CONFIGURE THE VERSION FOR SCALA
18-
RELEASEBUILD: yes
17+
# Release only happends when triggering CI by pushing tag
18+
RELEASEBUILD: ${{ startsWith(github.event.ref, 'refs/tags/') && 'yes' || 'no' }}
1919

2020
jobs:
2121
build:

.github/workflows/ci.yaml

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1163,7 +1163,15 @@ jobs:
11631163
if :
11641164
(github.event_name == 'pull_request' && contains(github.event.pull_request.body, '[test_msi]')) ||
11651165
(github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags/'))
1166-
# TODO: ADD A JOB THAT DEPENDS ON THIS TO TEST THE MSI
1166+
1167+
test-msi-package:
1168+
uses: ./.github/workflows/test-msi.yml
1169+
needs: [build-msi-package]
1170+
with:
1171+
# Ensure that version starts with prefix 3.
1172+
# In the future it can be adapted to compare with with git tag or version set in the build.s
1173+
version: "3."
1174+
java-version: 8
11671175

11681176
build-sdk-package:
11691177
uses: ./.github/workflows/build-sdk.yml

.github/workflows/publish-sdkman.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ jobs:
4646
- platform: WINDOWS_64
4747
archive : 'scala3-${{ inputs.version }}-x86_64-pc-win32.zip'
4848
steps:
49-
- uses: hamzaremmal/sdkman-release-action@1f2d4209b4f5a38721d4ae20014ea8e1689d869e
49+
- uses: sdkman/sdkman-release-action@1f2d4209b4f5a38721d4ae20014ea8e1689d869e
5050
with:
5151
CONSUMER-KEY : ${{ secrets.CONSUMER-KEY }}
5252
CONSUMER-TOKEN : ${{ secrets.CONSUMER-TOKEN }}
@@ -59,7 +59,7 @@ jobs:
5959
runs-on: ubuntu-latest
6060
needs: publish
6161
steps:
62-
- uses: hamzaremmal/sdkman-default-action@b3f991bd109e40155af1b13a4c6fc8e8ccada65e
62+
- uses: sdkman/sdkman-default-action@b3f991bd109e40155af1b13a4c6fc8e8ccada65e
6363
with:
6464
CONSUMER-KEY : ${{ secrets.CONSUMER-KEY }}
6565
CONSUMER-TOKEN : ${{ secrets.CONSUMER-TOKEN }}

.github/workflows/test-msi.yml

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
###################################################################################################
2+
### THIS IS A REUSABLE WORKFLOW TO TEST SCALA WITH MSI RUNNER ###
3+
### HOW TO USE: ###
4+
### Provide optional `version` to test if installed binaries are installed with ###
5+
### correct Scala version. ###
6+
### NOTE: Requires `scala.msi` artifact uploaded within the same run ###
7+
### ###
8+
###################################################################################################
9+
10+
name: Test 'scala' MSI Package
11+
run-name: Test 'scala' (${{ inputs.version }}) MSI Package
12+
13+
on:
14+
workflow_call:
15+
inputs:
16+
version:
17+
required: true
18+
type: string
19+
java-version:
20+
required: true
21+
type : string
22+
23+
jobs:
24+
test:
25+
runs-on: windows-latest
26+
steps:
27+
- uses: actions/setup-java@v4
28+
with:
29+
distribution: temurin
30+
java-version: ${{ inputs.java-version }}
31+
- name: Download MSI artifact
32+
uses: actions/download-artifact@v4
33+
with:
34+
name: scala.msi
35+
path: .
36+
37+
# Run the MSI installer
38+
# During normal installation msiexec would modify the PATH automatically.
39+
# However, it seems not to work in GH Actions. Append the PATH manually instead.
40+
- name: Install Scala Runner
41+
shell: pwsh
42+
run: |
43+
Start-Process 'msiexec.exe' -ArgumentList '/I "scala.msi" /L*V "install.log" /qb' -Wait
44+
Get-Content 'install.log'
45+
Add-Content $env:GITHUB_PATH "C:\Program Files (x86)\scala\bin"
46+
47+
# Run tests to ensure the Scala Runner was installed and works
48+
- name: Test Scala Runner
49+
shell: pwsh
50+
run: |
51+
scala --version
52+
if (-not (scala --version | Select-String "Scala version \(default\): ${{ inputs.version }}")) {
53+
Write-Host "Invalid Scala version of MSI installed runner, expected ${{ inputs.version }}"
54+
Exit 1
55+
}
56+
- name : Test the `scalac` command
57+
shell: pwsh
58+
run: |
59+
scalac --version
60+
if (-not (scalac --version | Select-String "Scala compiler version ${{ inputs.version }}")) {
61+
Write-Host "Invalid scalac version of MSI installed runner, expected ${{ inputs.version }}"
62+
Exit 1
63+
}
64+
- name : Test the `scaladoc` command
65+
shell: pwsh
66+
run: |
67+
scaladoc --version
68+
if (-not (scaladoc --version | Select-String "Scaladoc version ${{ inputs.version }}")) {
69+
Write-Host "Invalid scaladoc version of MSI installed runner, expected ${{ inputs.version }}"
70+
Exit 1
71+
}
72+
- name : Uninstall the `scala` package
73+
shell: pwsh
74+
run: |
75+
Start-Process 'msiexec.exe' -ArgumentList '/X "scala.msi" /L*V "uninstall.log" /qb' -Wait
76+
Get-Content 'uninstall.log'
77+

compiler/src/dotty/tools/dotc/ast/TreeInfo.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -142,9 +142,9 @@ trait TreeInfo[T <: Untyped] { self: Trees.Instance[T] =>
142142

143143
/** All term arguments of an application in a single flattened list */
144144
def allTermArguments(tree: Tree): List[Tree] = unsplice(tree) match {
145-
case Apply(fn, args) => allArguments(fn) ::: args
146-
case TypeApply(fn, args) => allArguments(fn)
147-
case Block(_, expr) => allArguments(expr)
145+
case Apply(fn, args) => allTermArguments(fn) ::: args
146+
case TypeApply(fn, args) => allTermArguments(fn)
147+
case Block(_, expr) => allTermArguments(expr)
148148
case _ => Nil
149149
}
150150

compiler/src/dotty/tools/dotc/ast/untpd.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -524,8 +524,8 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
524524
def makeRetaining(parent: Tree, refs: List[Tree], annotName: TypeName)(using Context): Annotated =
525525
Annotated(parent, New(scalaAnnotationDot(annotName), List(refs)))
526526

527-
def makeCapsOf(id: Ident)(using Context): Tree =
528-
TypeApply(Select(scalaDot(nme.caps), nme.capsOf), id :: Nil)
527+
def makeCapsOf(tp: RefTree)(using Context): Tree =
528+
TypeApply(Select(scalaDot(nme.caps), nme.capsOf), tp :: Nil)
529529

530530
def makeCapsBound()(using Context): Tree =
531531
makeRetaining(

compiler/src/dotty/tools/dotc/cc/CaptureOps.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ extension (tp: Type)
194194
true
195195
case tp: TermRef =>
196196
((tp.prefix eq NoPrefix)
197-
|| tp.symbol.is(ParamAccessor) && tp.prefix.isThisTypeOf(tp.symbol.owner)
197+
|| tp.symbol.isField && !tp.symbol.isStatic && tp.prefix.isTrackableRef
198198
|| tp.isRootCapability
199199
) && !tp.symbol.isOneOf(UnstableValueFlags)
200200
case tp: TypeRef =>

compiler/src/dotty/tools/dotc/cc/CaptureRef.scala

Lines changed: 40 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -61,18 +61,19 @@ trait CaptureRef extends TypeProxy, ValueType:
6161
case tp: TermParamRef => tp.underlying.derivesFrom(defn.Caps_Exists)
6262
case _ => false
6363

64-
/** Normalize reference so that it can be compared with `eq` for equality */
65-
final def normalizedRef(using Context): CaptureRef = this match
66-
case tp @ AnnotatedType(parent: CaptureRef, annot) if tp.isTrackableRef =>
67-
tp.derivedAnnotatedType(parent.normalizedRef, annot)
68-
case tp: TermRef if tp.isTrackableRef =>
69-
tp.symbol.termRef
70-
case _ => this
64+
// With the support of pathes, we don't need to normalize the `TermRef`s anymore.
65+
// /** Normalize reference so that it can be compared with `eq` for equality */
66+
// final def normalizedRef(using Context): CaptureRef = this match
67+
// case tp @ AnnotatedType(parent: CaptureRef, annot) if tp.isTrackableRef =>
68+
// tp.derivedAnnotatedType(parent.normalizedRef, annot)
69+
// case tp: TermRef if tp.isTrackableRef =>
70+
// tp.symbol.termRef
71+
// case _ => this
7172

7273
/** The capture set consisting of exactly this reference */
7374
final def singletonCaptureSet(using Context): CaptureSet.Const =
7475
if mySingletonCaptureSet == null then
75-
mySingletonCaptureSet = CaptureSet(this.normalizedRef)
76+
mySingletonCaptureSet = CaptureSet(this)
7677
mySingletonCaptureSet.uncheckedNN
7778

7879
/** The capture set of the type underlying this reference */
@@ -97,27 +98,51 @@ trait CaptureRef extends TypeProxy, ValueType:
9798
* x subsumes y ==> x* subsumes y, x subsumes y?
9899
* x subsumes y ==> x* subsumes y*, x? subsumes y?
99100
* x: x1.type /\ x1 subsumes y ==> x subsumes y
101+
* TODO: Document path cases
100102
*/
101103
final def subsumes(y: CaptureRef)(using Context): Boolean =
104+
105+
def subsumingRefs(x: Type, y: Type): Boolean = x match
106+
case x: CaptureRef => y match
107+
case y: CaptureRef => x.subsumes(y)
108+
case _ => false
109+
case _ => false
110+
111+
def viaInfo(info: Type)(test: Type => Boolean): Boolean = info.match
112+
case info: SingletonCaptureRef => test(info)
113+
case info: AndType => viaInfo(info.tp1)(test) || viaInfo(info.tp2)(test)
114+
case info: OrType => viaInfo(info.tp1)(test) && viaInfo(info.tp2)(test)
115+
case _ => false
116+
102117
(this eq y)
103118
|| this.isRootCapability
104119
|| y.match
105120
case y: TermRef =>
106-
(y.prefix eq this)
107-
|| y.info.match
108-
case y1: SingletonCaptureRef => this.subsumes(y1)
121+
y.prefix.match
122+
case ypre: CaptureRef =>
123+
this.subsumes(ypre)
124+
|| this.match
125+
case x @ TermRef(xpre: CaptureRef, _) if x.symbol == y.symbol =>
126+
// To show `{x.f} <:< {y.f}`, it is important to prove `x` and `y`
127+
// are equvalent, which means `x =:= y` in terms of subtyping,
128+
// not just `{x} =:= {y}` in terms of subcapturing.
129+
// It is possible to construct two singleton types `x` and `y`,
130+
// which subsume each other, but are not equal references.
131+
// See `tests/neg-custom-args/captures/path-prefix.scala` for example.
132+
withMode(Mode.IgnoreCaptures) {TypeComparer.isSameRef(xpre, ypre)}
133+
case _ =>
134+
false
109135
case _ => false
136+
|| viaInfo(y.info)(subsumingRefs(this, _))
110137
case MaybeCapability(y1) => this.stripMaybe.subsumes(y1)
111138
case _ => false
112139
|| this.match
113140
case ReachCapability(x1) => x1.subsumes(y.stripReach)
114-
case x: TermRef =>
115-
x.info match
116-
case x1: SingletonCaptureRef => x1.subsumes(y)
117-
case _ => false
141+
case x: TermRef => viaInfo(x.info)(subsumingRefs(_, y))
118142
case x: TermParamRef => subsumesExistentially(x, y)
119143
case x: TypeRef => assumedContainsOf(x).contains(y)
120144
case _ => false
145+
end subsumes
121146

122147
def assumedContainsOf(x: TypeRef)(using Context): SimpleIdentitySet[CaptureRef] =
123148
CaptureSet.assumedContains.getOrElse(x, SimpleIdentitySet.empty)

compiler/src/dotty/tools/dotc/cc/CaptureSet.scala

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -374,7 +374,7 @@ object CaptureSet:
374374

375375
def apply(elems: CaptureRef*)(using Context): CaptureSet.Const =
376376
if elems.isEmpty then empty
377-
else Const(SimpleIdentitySet(elems.map(_.normalizedRef.ensuring(_.isTrackableRef))*))
377+
else Const(SimpleIdentitySet(elems.map(_.ensuring(_.isTrackableRef))*))
378378

379379
def apply(elems: Refs)(using Context): CaptureSet.Const =
380380
if elems.isEmpty then empty else Const(elems)
@@ -508,7 +508,11 @@ object CaptureSet:
508508
!noUniversal
509509
else elem match
510510
case elem: TermRef if level.isDefined =>
511-
elem.symbol.ccLevel <= level
511+
elem.prefix match
512+
case prefix: CaptureRef =>
513+
levelOK(prefix)
514+
case _ =>
515+
elem.symbol.ccLevel <= level
512516
case elem: ThisType if level.isDefined =>
513517
elem.cls.ccLevel.nextInner <= level
514518
case ReachCapability(elem1) =>

0 commit comments

Comments
 (0)