Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions eng/Build.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ param (

Set-StrictMode -version 2.0
$ErrorActionPreference = "Stop"
$BuildCategory = ""
$BuildMessage = ""

function Print-Usage() {
Write-Host "Common settings:"
Expand Down Expand Up @@ -303,6 +305,9 @@ function EnablePreviewSdks() {
}

try {
$script:BuildCategory = "Build"
$script:BuildMessage = "Failure preparing build"

Process-Arguments

. (Join-Path $PSScriptRoot "build-utils.ps1")
Expand All @@ -317,9 +322,11 @@ try {
}

if ($bootstrap) {
$script:BuildMessage = "Failure building bootstrap compiler"
$bootstrapDir = Make-BootstrapBuild
}

$script:BuildMessage = "Failure building product"
if ($restore -or $build -or $rebuild -or $pack -or $sign -or $publish) {
if ($noVisualStudio) {
BuildCompiler
Expand All @@ -332,6 +339,8 @@ try {
VerifyAssemblyVersionsAndSymbols
}

$script:BuildCategory = "Test"
$script:BuildMessage = "Failure running tests"
$desktopTargetFramework = "net472"
$coreclrTargetFramework = "netcoreapp3.0"

Expand Down Expand Up @@ -421,6 +430,7 @@ catch {
Write-Host $_
Write-Host $_.Exception
Write-Host $_.ScriptStackTrace
Write-PipelineTelemetryError -Category $script:BuildCategory -Message $script:BuildMessage
ExitWithExitCode 1
}
finally {
Expand Down
1 change: 1 addition & 0 deletions eng/Versions.props
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@
<SystemThreadingThreadVersion>4.3.0</SystemThreadingThreadVersion>
<SystemThreadingThreadPoolVersion>4.3.0</SystemThreadingThreadPoolVersion>
<SystemValueTupleVersion>4.5.0</SystemValueTupleVersion>
<SystemBuffersVersion>4.5.0</SystemBuffersVersion>
<!-- Roslyn packages -->
<MicrosoftCodeAnalysisEditorFeaturesVersion>$(RoslynVersion)</MicrosoftCodeAnalysisEditorFeaturesVersion>
<MicrosoftCodeAnalysisEditorFeaturesTextVersion>$(RoslynVersion)</MicrosoftCodeAnalysisEditorFeaturesTextVersion>
Expand Down
46 changes: 25 additions & 21 deletions eng/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ properties=""
docker=false
args=""

BuildCategory=""
BuildMessage=""

if [[ $# = 0 ]]
then
usage
Expand Down Expand Up @@ -150,6 +153,8 @@ done
. "$scriptroot/common/tools.sh"

function TestUsingNUnit() {
BuildCategory="Test"
BuildMessage="Error running tests"
testproject=""
targetframework=""
while [[ $# > 0 ]]; do
Expand Down Expand Up @@ -180,14 +185,12 @@ function TestUsingNUnit() {
projectname="${projectname%.*}"
testlogpath="$artifacts_dir/TestResults/$configuration/${projectname}_$targetframework.xml"
args="test \"$testproject\" --no-restore --no-build -c $configuration -f $targetframework --test-adapter-path . --logger \"nunit;LogFilePath=$testlogpath\""
"$DOTNET_INSTALL_DIR/dotnet" $args || {
local exit_code=$?
Write-PipelineTelemetryError -category 'Test' "dotnet test failed for $testproject:$targetframework (exit code $exit_code)."
ExitWithExitCode $exit_code
}
"$DOTNET_INSTALL_DIR/dotnet" $args || exit $?
}

function BuildSolution {
BuildCategory="Build"
BuildMessage="Error preparing build"
local solution="FSharp.sln"
echo "$solution:"

Expand Down Expand Up @@ -229,33 +232,28 @@ function BuildSolution {
rm -fr $bootstrap_dir
fi
if [ ! -f "$bootstrap_dir/fslex.dll" ]; then
BuildMessage="Error building tools"
MSBuild "$repo_root/src/buildtools/buildtools.proj" \
/restore \
/p:Configuration=$bootstrap_config \
/t:Publish || {
local exit_code=$?
Write-PipelineTelemetryError -category 'Build' "Error building buildtools (exit code '$exit_code')."
ExitWithExitCode $exit_code
}
/t:Publish

mkdir -p "$bootstrap_dir"
cp -pr $artifacts_dir/bin/fslex/$bootstrap_config/netcoreapp3.0/publish $bootstrap_dir/fslex
cp -pr $artifacts_dir/bin/fsyacc/$bootstrap_config/netcoreapp3.0/publish $bootstrap_dir/fsyacc
fi
if [ ! -f "$bootstrap_dir/fsc.exe" ]; then
BuildMessage="Error building bootstrap"
MSBuild "$repo_root/proto.proj" \
/restore \
/p:Configuration=$bootstrap_config \
/t:Publish || {
local exit_code=$?
Write-PipelineTelemetryError -category 'Build' "Error building bootstrap compiler (exit code '$exit_code')."
ExitWithExitCode $exit_code
}
/t:Publish

cp -pr $artifacts_dir/bin/fsc/$bootstrap_config/netcoreapp3.0/publish $bootstrap_dir/fsc
fi

# do real build
BuildMessage="Error building solution"
MSBuild $toolset_build_proj \
$bl \
/v:$verbosity \
Expand All @@ -271,13 +269,20 @@ function BuildSolution {
/p:ContinuousIntegrationBuild=$ci \
/p:QuietRestore=$quiet_restore \
/p:QuietRestoreBinaryLog="$binary_log" \
$properties || {
local exit_code=$?
Write-PipelineTelemetryError -category 'Build' "Error building solution (exit code '$exit_code')."
ExitWithExitCode $exit_code
}
$properties
}

function TrapAndReportError {
local exit_code=$?
if [[ ! $exit_code == 0 ]]; then
Write-PipelineTelemetryError -category $BuildCategory "$BuildMessage (exit code '$exit_code')."
ExitWithExitCode $exit_code
fi
}

# allow early termination to report the appropriate build failure reason
trap TrapAndReportError EXIT

InitializeDotNetCli $restore

BuildSolution
Expand All @@ -293,4 +298,3 @@ if [[ "$test_core_clr" == true ]]; then
fi

ExitWithExitCode 0

1 change: 1 addition & 0 deletions fcs/FSharp.Compiler.Service/FSharp.Compiler.Service.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -680,6 +680,7 @@
<PackageReference Include="FSharp.Core" Version="$(FcsFSharpCorePkgVersion)" />
<PackageReference Include="System.Collections.Immutable" Version="1.5.0" />
<PackageReference Include="System.Reflection.Metadata" Version="1.6.0" />
<PackageReference Include="System.Buffers" Version="4.5.0" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
<PackageReference Include="System.Diagnostics.Process" Version="4.1.0" />
Expand Down
7 changes: 4 additions & 3 deletions src/absil/bytes.fs
Original file line number Diff line number Diff line change
Expand Up @@ -306,10 +306,11 @@ type ByteMemory with
leaveOpen=false)
mmf, mmf.CreateViewAccessor(0L, length, memoryMappedFileAccess), length

// Validate MMF with the access that was intended.
match access with
| FileAccess.Read when not accessor.CanRead -> failwith "Cannot read file"
| FileAccess.Write when not accessor.CanWrite -> failwith "Cannot write file"
| _ when not accessor.CanRead || not accessor.CanWrite -> failwith "Cannot read or write file"
| FileAccess.Read when not accessor.CanRead -> invalidOp "Cannot read file"
| FileAccess.Write when not accessor.CanWrite -> invalidOp "Cannot write file"
| FileAccess.ReadWrite when not accessor.CanRead || not accessor.CanWrite -> invalidOp "Cannot read or write file"
| _ -> ()

let safeHolder =
Expand Down
60 changes: 39 additions & 21 deletions src/fsharp/CompileOps.fs
Original file line number Diff line number Diff line change
Expand Up @@ -3756,6 +3756,38 @@ type TcConfigProvider =
// TcImports
//--------------------------------------------------------------------------

[<Sealed>]
type TcImportsSafeDisposal
(disposeActions: ResizeArray<unit -> unit>,
#if !NO_EXTENSIONTYPING
disposeTypeProviderActions: ResizeArray<unit -> unit>,
#endif
compilationThread: ICompilationThread) =

let mutable isDisposed = false

let dispose () =
// disposing deliberately only closes this tcImports, not the ones up the chain
isDisposed <- true
if verbose then
dprintf "disposing of TcImports, %d binaries\n" disposeActions.Count
#if !NO_EXTENSIONTYPING
let actions = disposeTypeProviderActions
if actions.Count > 0 then
compilationThread.EnqueueWork (fun _ -> for action in actions do action())
#endif
for action in disposeActions do action()

override _.Finalize() =
dispose ()

interface IDisposable with

member this.Dispose() =
if not isDisposed then
GC.SuppressFinalize this
dispose ()

#if !NO_EXTENSIONTYPING
// These are hacks in order to allow TcImports to be held as a weak reference inside a type provider.
// The reason is due to older type providers compiled using an older TypeProviderSDK, that SDK used reflection on fields and properties to determine the contract.
Expand Down Expand Up @@ -3800,34 +3832,24 @@ and [<Sealed>] TcImports(tcConfigP: TcConfigProvider, initialResolutions: TcAsse
let mutable dllTable: NameMap<ImportedBinary> = NameMap.empty
let mutable ccuInfos: ImportedAssembly list = []
let mutable ccuTable: NameMap<ImportedAssembly> = NameMap.empty
let mutable disposeActions = []
let disposeActions = ResizeArray()
let mutable disposed = false
let mutable ilGlobalsOpt = ilGlobalsOpt
let mutable tcGlobals = None
#if !NO_EXTENSIONTYPING
let mutable disposeTypeProviderActions = []
let disposeTypeProviderActions = ResizeArray()
let mutable generatedTypeRoots = new System.Collections.Generic.Dictionary<ILTypeRef, int * ProviderGeneratedType>()
let mutable tcImportsWeak = TcImportsWeakHack (WeakReference<_> this)
#endif

let disposal = new TcImportsSafeDisposal(disposeActions, disposeTypeProviderActions, compilationThread)

let CheckDisposed() =
if disposed then assert false

let dispose () =
CheckDisposed()
// disposing deliberately only closes this tcImports, not the ones up the chain
disposed <- true
if verbose then
dprintf "disposing of TcImports, %d binaries\n" disposeActions.Length
#if !NO_EXTENSIONTYPING
let actions = disposeTypeProviderActions
disposeTypeProviderActions <- []
if actions.Length > 0 then
compilationThread.EnqueueWork (fun _ -> for action in actions do action())
#endif
let actions = disposeActions
disposeActions <- []
for action in actions do action()
(disposal :> IDisposable).Dispose()

static let ccuHasType (ccu: CcuThunk) (nsname: string list) (tname: string) =
let matchNameSpace (entityOpt: Entity option) n =
Expand Down Expand Up @@ -4043,12 +4065,12 @@ and [<Sealed>] TcImports(tcConfigP: TcConfigProvider, initialResolutions: TcAsse

member private tcImports.AttachDisposeAction action =
CheckDisposed()
disposeActions <- action :: disposeActions
disposeActions.Add action

#if !NO_EXTENSIONTYPING
member private tcImports.AttachDisposeTypeProviderAction action =
CheckDisposed()
disposeTypeProviderActions <- action :: disposeTypeProviderActions
disposeTypeProviderActions.Add action
#endif

// Note: the returned binary reader is associated with the tcImports, i.e. when the tcImports are closed
Expand Down Expand Up @@ -4781,9 +4803,6 @@ and [<Sealed>] TcImports(tcConfigP: TcConfigProvider, initialResolutions: TcAsse
knownUnresolved
|> List.map (function UnresolvedAssemblyReference(file, originalReferences) -> file, originalReferences)
|> List.iter reportAssemblyNotResolved

override tcImports.Finalize () =
dispose ()

static member BuildNonFrameworkTcImports (ctok, tcConfigP: TcConfigProvider, tcGlobals: TcGlobals, baseTcImports, nonFrameworkReferences, knownUnresolved) =
cancellable {
Expand All @@ -4809,7 +4828,6 @@ and [<Sealed>] TcImports(tcConfigP: TcConfigProvider, initialResolutions: TcAsse
interface System.IDisposable with
member tcImports.Dispose() =
dispose ()
GC.SuppressFinalize tcImports

override tcImports.ToString() = "TcImports(...)"

Expand Down
73 changes: 45 additions & 28 deletions src/fsharp/ConstraintSolver.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -47,34 +47,48 @@ val FreshenMethInfo : range -> MethInfo -> TType list
[<RequireQualifiedAccess>]
/// Information about the context of a type equation.
type ContextInfo =
/// No context was given.
| NoContext
/// The type equation comes from an IF expression.
| IfExpression of range
/// The type equation comes from an omitted else branch.
| OmittedElseBranch of range
/// The type equation comes from a type check of the result of an else branch.
| ElseBranchResult of range
/// The type equation comes from the verification of record fields.
| RecordFields
/// The type equation comes from the verification of a tuple in record fields.
| TupleInRecordFields
/// The type equation comes from a list or array constructor
| CollectionElement of bool * range
/// The type equation comes from a return in a computation expression.
| ReturnInComputationExpression
/// The type equation comes from a yield in a computation expression.
| YieldInComputationExpression
/// The type equation comes from a runtime type test.
| RuntimeTypeTest of bool
/// The type equation comes from an downcast where a upcast could be used.
| DowncastUsedInsteadOfUpcast of bool
/// The type equation comes from a return type of a pattern match clause (not the first clause).
| FollowingPatternMatchClause of range
/// The type equation comes from a pattern match guard.
| PatternMatchGuard of range
/// The type equation comes from a sequence expression.
| SequenceExpression of TType

/// No context was given.
| NoContext

/// The type equation comes from an IF expression.
| IfExpression of range

/// The type equation comes from an omitted else branch.
| OmittedElseBranch of range

/// The type equation comes from a type check of the result of an else branch.
| ElseBranchResult of range

/// The type equation comes from the verification of record fields.
| RecordFields

/// The type equation comes from the verification of a tuple in record fields.
| TupleInRecordFields

/// The type equation comes from a list or array constructor
| CollectionElement of bool * range

/// The type equation comes from a return in a computation expression.
| ReturnInComputationExpression

/// The type equation comes from a yield in a computation expression.
| YieldInComputationExpression

/// The type equation comes from a runtime type test.
| RuntimeTypeTest of bool

/// The type equation comes from an downcast where a upcast could be used.
| DowncastUsedInsteadOfUpcast of bool

/// The type equation comes from a return type of a pattern match clause (not the first clause).
| FollowingPatternMatchClause of range

/// The type equation comes from a pattern match guard.
| PatternMatchGuard of range

/// The type equation comes from a sequence expression.
| SequenceExpression of TType

exception ConstraintSolverTupleDiffLengths of displayEnv: DisplayEnv * TType list * TType list * range * range
exception ConstraintSolverInfiniteTypes of displayEnv: DisplayEnv * contextInfo: ContextInfo * TType * TType * range * range
Expand Down Expand Up @@ -116,7 +130,10 @@ type OptionalTrace =
val SimplifyMeasuresInTypeScheme : TcGlobals -> bool -> Typars -> TType -> TyparConstraint list -> Typars
val SolveTyparEqualsType : ConstraintSolverEnv -> int -> range -> OptionalTrace -> TType -> TType -> OperationResult<unit>
val SolveTypeEqualsTypeKeepAbbrevs : ConstraintSolverEnv -> int -> range -> OptionalTrace -> TType -> TType -> OperationResult<unit>

/// Canonicalize constraints prior to generalization
val CanonicalizeRelevantMemberConstraints : ConstraintSolverEnv -> int -> OptionalTrace -> Typars -> OperationResult<unit>

val ResolveOverloading : ConstraintSolverEnv -> OptionalTrace -> string -> ndeep: int -> TraitConstraintInfo option -> int * int -> AccessorDomain -> CalledMeth<Expr> list -> bool -> TType option -> CalledMeth<Expr> option * OperationResult<unit>
val UnifyUniqueOverloading : ConstraintSolverEnv -> int * int -> string -> AccessorDomain -> CalledMeth<SynExpr> list -> TType -> OperationResult<bool>
val EliminateConstraintsForGeneralizedTypars : ConstraintSolverEnv -> OptionalTrace -> Typars -> unit
Expand Down
Loading