Skip to content

Commit 5455a09

Browse files
authored
Merge pull request #9375 from dotnet/merges/master-to-release/dev16.7
Merge master to release/dev16.7
2 parents f2812f7 + ed9b9b7 commit 5455a09

Some content is hidden

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

42 files changed

+3830
-818
lines changed

src/fsharp/ConstraintSolver.fs

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,11 @@ type ConstraintSolverState =
245245
/// The function used to freshen values we encounter during trait constraint solving
246246
TcVal: TcValF
247247

248+
/// Indicates if the constraint solver is being run after type checking is complete,
249+
/// e.g. during codegen to determine solutions and witnesses for trait constraints.
250+
/// Suppresses the generation of certain errors such as missing constraint warnings.
251+
codegen: bool
252+
248253
/// This table stores all unsolved, ungeneralized trait constraints, indexed by free type variable.
249254
/// That is, there will be one entry in this table for each free type variable in
250255
/// each outstanding, unsolved, ungeneralized trait constraint. Constraints are removed from the table and resolved
@@ -257,6 +262,7 @@ type ConstraintSolverState =
257262
amap = amap
258263
ExtraCxs = HashMultiMap(10, HashIdentity.Structural)
259264
InfoReader = infoReader
265+
codegen = false
260266
TcVal = tcVal }
261267

262268
type ConstraintSolverEnv =
@@ -1939,14 +1945,14 @@ and AddConstraint (csenv: ConstraintSolverEnv) ndeep m2 trace tp newConstraint
19391945
| (TyparRigidity.Rigid | TyparRigidity.WillBeRigid), TyparConstraint.DefaultsTo _ -> true
19401946
| _ -> false) then
19411947
()
1942-
elif tp.Rigidity = TyparRigidity.Rigid then
1948+
elif tp.Rigidity = TyparRigidity.Rigid && not csenv.SolverState.codegen then
19431949
return! ErrorD (ConstraintSolverMissingConstraint(denv, tp, newConstraint, m, m2))
19441950
else
19451951
// It is important that we give a warning if a constraint is missing from a
19461952
// will-be-made-rigid type variable. This is because the existence of these warnings
19471953
// is relevant to the overload resolution rules (see 'candidateWarnCount' in the overload resolution
19481954
// implementation).
1949-
if tp.Rigidity.WarnIfMissingConstraint then
1955+
if tp.Rigidity.WarnIfMissingConstraint && not csenv.SolverState.codegen then
19501956
do! WarnD (ConstraintSolverMissingConstraint(denv, tp, newConstraint, m, m2))
19511957

19521958
let newConstraints =
@@ -3059,20 +3065,36 @@ let CreateCodegenState tcVal g amap =
30593065
amap = amap
30603066
TcVal = tcVal
30613067
ExtraCxs = HashMultiMap(10, HashIdentity.Structural)
3062-
InfoReader = new InfoReader(g, amap) }
3068+
InfoReader = new InfoReader(g, amap)
3069+
codegen = true }
30633070

30643071
/// Generate a witness expression if none is otherwise available, e.g. in legacy non-witness-passing code
3065-
let CodegenWitnessForTraitConstraint tcVal g amap m (traitInfo: TraitConstraintInfo) argExprs = trackErrors {
3072+
let CodegenWitnessForTraitConstraint tcVal g amap m (traitInfo:TraitConstraintInfo) argExprs = trackErrors {
30663073
let css = CreateCodegenState tcVal g amap
3067-
30683074
let csenv = MakeConstraintSolverEnv ContextInfo.NoContext css m (DisplayEnv.Empty g)
3069-
30703075
let! _res = SolveMemberConstraint csenv true PermitWeakResolution.Yes 0 m NoTrace traitInfo
3071-
30723076
let sln = GenWitnessExpr amap g m traitInfo argExprs
30733077
return sln
30743078
}
30753079

3080+
/// Generate the lambda argument passed for a use of a generic construct that accepts trait witnesses
3081+
let CodegenWitnessesForTyparInst tcVal g amap m typars tyargs = trackErrors {
3082+
let css = CreateCodegenState tcVal g amap
3083+
let csenv = MakeConstraintSolverEnv ContextInfo.NoContext css m (DisplayEnv.Empty g)
3084+
let ftps, _renaming, tinst = FreshenTypeInst m typars
3085+
let traitInfos = GetTraitConstraintInfosOfTypars g ftps
3086+
do! SolveTypeEqualsTypeEqns csenv 0 m NoTrace None tinst tyargs
3087+
return MethodCalls.GenWitnessArgs amap g m traitInfos
3088+
}
3089+
3090+
/// Generate the lambda argument passed for a use of a generic construct that accepts trait witnesses
3091+
let CodegenWitnessesForTraitWitness tcVal g amap m traitInfo = trackErrors {
3092+
let css = CreateCodegenState tcVal g amap
3093+
let csenv = MakeConstraintSolverEnv ContextInfo.NoContext css m (DisplayEnv.Empty g)
3094+
let! _res = SolveMemberConstraint csenv true PermitWeakResolution.Yes 0 m NoTrace traitInfo
3095+
return MethodCalls.GenWitnessExprLambda amap g m traitInfo
3096+
}
3097+
30763098
/// For some code like "let f() = ([] = [])", a free choice is made for a type parameter
30773099
/// for an interior type variable. This chooses a solution for a type parameter subject
30783100
/// to its constraints and applies that solution by using a constraint.
@@ -3118,6 +3140,7 @@ let IsApplicableMethApprox g amap m (minfo: MethInfo) availObjTy =
31183140
amap = amap
31193141
TcVal = (fun _ -> failwith "should not be called")
31203142
ExtraCxs = HashMultiMap(10, HashIdentity.Structural)
3143+
codegen = false
31213144
InfoReader = new InfoReader(g, amap) }
31223145
let csenv = MakeConstraintSolverEnv ContextInfo.NoContext css m (DisplayEnv.Empty g)
31233146
let minst = FreshenMethInfo m minfo

src/fsharp/ConstraintSolver.fsi

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -192,12 +192,18 @@ val SolveTypeAsError: DisplayEnv -> ConstraintSolverState -> range -> TType -> u
192192
val ApplyTyparDefaultAtPriority: DisplayEnv -> ConstraintSolverState -> priority: int -> Typar -> unit
193193

194194
/// Generate a witness expression if none is otherwise available, e.g. in legacy non-witness-passing code
195-
val CodegenWitnessForTraitConstraint: TcValF -> TcGlobals -> ImportMap -> range -> TraitConstraintInfo -> Expr list -> OperationResult<Expr option>
195+
val CodegenWitnessForTraitConstraint : TcValF -> TcGlobals -> ImportMap -> range -> TraitConstraintInfo -> Expr list -> OperationResult<Expr option>
196+
197+
/// Generate the arguments passed when using a generic construct that accepts traits witnesses
198+
val CodegenWitnessesForTyparInst : TcValF -> TcGlobals -> ImportMap -> range -> Typars -> TType list -> OperationResult<Choice<TraitConstraintInfo, Expr> list>
199+
200+
/// Generate the lambda argument passed for a use of a generic construct that accepts trait witnesses
201+
val CodegenWitnessesForTraitWitness : TcValF -> TcGlobals -> ImportMap -> range -> TraitConstraintInfo -> OperationResult<Choice<TraitConstraintInfo, Expr>>
196202

197203
/// For some code like "let f() = ([] = [])", a free choice is made for a type parameter
198204
/// for an interior type variable. This chooses a solution for a type parameter subject
199205
/// to its constraints and applies that solution by using a constraint.
200-
val ChooseTyparSolutionAndSolve: ConstraintSolverState -> DisplayEnv -> Typar -> unit
206+
val ChooseTyparSolutionAndSolve : ConstraintSolverState -> DisplayEnv -> Typar -> unit
201207

202208
val IsApplicableMethApprox: TcGlobals -> ImportMap -> range -> MethInfo -> TType -> bool
203209

src/fsharp/FSComp.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1512,3 +1512,4 @@ featureFixedIndexSlice3d4d,"fixed-index slice 3d/4d"
15121512
featureAndBang,"applicative computation expressions"
15131513
featureNullableOptionalInterop,"nullable optional interop"
15141514
featureDefaultInterfaceMemberConsumption,"default interface member consumption"
1515+
featureWitnessPassing,"witness passing"

src/fsharp/FSharp.Compiler.Private/FSharp.Compiler.Private.fsproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -406,10 +406,10 @@
406406
<Link>TypedTree\TypedTreeOps.fs</Link>
407407
</Compile>
408408
<Compile Include="..\TypedTreePickle.fsi">
409-
<Link>TypedTree\.TypedTreePickle.fsi</Link>
409+
<Link>TypedTree\TypedTreePickle.fsi</Link>
410410
</Compile>
411411
<Compile Include="..\TypedTreePickle.fs">
412-
<Link>TypedTree\.TypedTreePickle.fs</Link>
412+
<Link>TypedTree\TypedTreePickle.fs</Link>
413413
</Compile>
414414
<Compile Include="..\import.fsi">
415415
<Link>Logic\import.fsi</Link>

src/fsharp/FSharp.Core/Linq.fs

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -396,7 +396,7 @@ module LeafExpressionConverter =
396396
| NullableGreaterEqNullableQ _ -> transBinOp inp env false args false Expression.GreaterThanOrEqual
397397
| NullableLessNullableQ _ -> transBinOp inp env false args false Expression.LessThan
398398
| NullableLessEqNullableQ _ -> transBinOp inp env false args false Expression.LessThanOrEqual
399-
399+
400400
// Detect the F# quotation encoding of decimal literals
401401
| MakeDecimalQ (_, _, [Int32 lo; Int32 med; Int32 hi; Bool isNegative; Byte scale]) ->
402402
Expression.Constant (new System.Decimal(lo, med, hi, isNegative, scale)) |> asExpr
@@ -414,33 +414,33 @@ module LeafExpressionConverter =
414414
| BitwiseOrQ _ -> transBinOp inp env false args false Expression.Or
415415
| BitwiseXorQ _ -> transBinOp inp env false args false Expression.ExclusiveOr
416416
| BitwiseNotQ (_, _, [x1]) -> Expression.Not(ConvExprToLinqInContext env x1) |> asExpr
417-
418-
| CheckedNeg (_, _, [x1]) -> Expression.NegateChecked(ConvExprToLinqInContext env x1) |> asExpr
417+
418+
| CheckedNeg (_, _, [x1]) -> Expression.NegateChecked(ConvExprToLinqInContext env x1) |> asExpr
419419
| CheckedPlusQ _ -> transBinOp inp env false args false Expression.AddChecked
420420
| CheckedMinusQ _ -> transBinOp inp env false args false Expression.SubtractChecked
421421
| CheckedMultiplyQ _ -> transBinOp inp env false args false Expression.MultiplyChecked
422-
422+
423423
| NullablePlusQ _ -> transBinOp inp env false args true Expression.Add
424424
| PlusNullableQ _ -> transBinOp inp env true args false Expression.Add
425425
| NullablePlusNullableQ _ -> transBinOp inp env false args false Expression.Add
426-
426+
427427
| NullableMinusQ _ -> transBinOp inp env false args true Expression.Subtract
428428
| MinusNullableQ _ -> transBinOp inp env true args false Expression.Subtract
429429
| NullableMinusNullableQ _ -> transBinOp inp env false args false Expression.Subtract
430-
430+
431431
| NullableMultiplyQ _ -> transBinOp inp env false args true Expression.Multiply
432432
| MultiplyNullableQ _ -> transBinOp inp env true args false Expression.Multiply
433433
| NullableMultiplyNullableQ _ -> transBinOp inp env false args false Expression.Multiply
434-
434+
435435
| NullableDivideQ _ -> transBinOp inp env false args true Expression.Divide
436436
| DivideNullableQ _ -> transBinOp inp env true args false Expression.Divide
437437
| NullableDivideNullableQ _ -> transBinOp inp env false args false Expression.Divide
438-
438+
439439
| NullableModuloQ _ -> transBinOp inp env false args true Expression.Modulo
440440
| ModuloNullableQ _ -> transBinOp inp env true args false Expression.Modulo
441441
| NullableModuloNullableQ _ -> transBinOp inp env false args false Expression.Modulo
442442

443-
| ConvNullableCharQ (_, _, [x1]) -> Expression.Convert(ConvExprToLinqInContext env x1, typeof<Nullable<char>>) |> asExpr
443+
| ConvNullableCharQ (_, _, [x1]) -> Expression.Convert(ConvExprToLinqInContext env x1, typeof<Nullable<char>>) |> asExpr
444444
| ConvNullableDecimalQ (_, _, [x1]) -> Expression.Convert(ConvExprToLinqInContext env x1, typeof<Nullable<decimal>>) |> asExpr
445445
| ConvNullableFloatQ (_, _, [x1]) -> Expression.Convert(ConvExprToLinqInContext env x1, typeof<Nullable<float>>) |> asExpr
446446
| ConvNullableDoubleQ (_, _, [x1]) -> Expression.Convert(ConvExprToLinqInContext env x1, typeof<Nullable<double>>) |> asExpr
@@ -496,10 +496,19 @@ module LeafExpressionConverter =
496496
// Throw away markers inserted to satisfy C#'s design where they pass an argument
497497
// or type T to an argument expecting Expression<T>.
498498
| ImplicitExpressionConversionHelperQ (_, [_], [x1]) -> ConvExprToLinqInContext env x1
499-
500-
| _ ->
501-
let argsP = ConvExprsToLinq env args
502-
Expression.Call(ConvObjArg env objOpt None, minfo, argsP) |> asExpr
499+
500+
/// Use witnesses if they are available
501+
| CallWithWitnesses (objArgOpt, _, minfo2, witnessArgs, args) ->
502+
let fullArgs = witnessArgs @ args
503+
let replacementExpr =
504+
match objArgOpt with
505+
| None -> Expr.Call(minfo2, fullArgs)
506+
| Some objArg -> Expr.Call(objArg, minfo2, fullArgs)
507+
ConvExprToLinqInContext env replacementExpr
508+
509+
| _ ->
510+
let argsP = ConvExprsToLinq env args
511+
Expression.Call(ConvObjArg env objOpt None, minfo, argsP) |> asExpr
503512

504513
#if !NO_CURRIED_FUNCTION_OPTIMIZATIONS
505514
// f x1 x2 x3 x4 --> InvokeFast4
@@ -650,12 +659,11 @@ module LeafExpressionConverter =
650659
let convType = lambdaTy.MakeGenericType tyargs
651660
let convDelegate = Expression.Lambda(convType, bodyP, [| vP |]) |> asExpr
652661
Expression.Call(typeof<FuncConvert>, "ToFSharpFunc", tyargs, [| convDelegate |]) |> asExpr
653-
654662
| _ ->
655663
failConvert inp
656664

657665
and failConvert inp =
658-
raise (new NotSupportedException(Printf.sprintf "Could not convert the following F# Quotation to a LINQ Expression Tree\n--------\n%A\n-------------\n" inp))
666+
raise (new NotSupportedException(Printf.sprintf "Could not convert the following F# Quotation to a LINQ Expression Tree\n--------\n%A\n-------------\n" inp))
659667

660668
and transBinOp inp env addConvertLeft args addConvertRight (exprErasedConstructor : _ * _ -> _) =
661669
match args with

src/fsharp/FSharp.Core/nativeptr.fsi

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,31 +12,27 @@ namespace Microsoft.FSharp.NativeInterop
1212
module NativePtr =
1313

1414
[<Unverifiable>]
15-
[<NoDynamicInvocation>]
1615
[<CompiledName("OfNativeIntInlined")>]
1716
/// <summary>Returns a typed native pointer for a given machine address.</summary>
1817
/// <param name="address">The pointer address.</param>
1918
/// <returns>A typed pointer.</returns>
2019
val inline ofNativeInt : address:nativeint -> nativeptr<'T>
2120

2221
[<Unverifiable>]
23-
[<NoDynamicInvocation>]
2422
[<CompiledName("ToVoidPtrInlined")>]
2523
/// <summary>Returns an untyped native pointer for a given typed pointer.</summary>
2624
/// <param name="address">The pointer address.</param>
2725
/// <returns>A typed pointer.</returns>
2826
val inline toVoidPtr : address:nativeptr<'T> -> voidptr
2927

3028
[<Unverifiable>]
31-
[<NoDynamicInvocation>]
3229
[<CompiledName("OfVoidPtrInlined")>]
3330
/// <summary>Returns a typed native pointer for a untyped native pointer.</summary>
3431
/// <param name="address">The untyped pointer.</param>
3532
/// <returns>A typed pointer.</returns>
3633
val inline ofVoidPtr : voidptr -> nativeptr<'T>
3734

3835
[<Unverifiable>]
39-
[<NoDynamicInvocation>]
4036
[<CompiledName("ToNativeIntInlined")>]
4137
/// <summary>Returns a machine address for a given typed native pointer.</summary>
4238
/// <param name="address">The input pointer.</param>
@@ -45,7 +41,6 @@ namespace Microsoft.FSharp.NativeInterop
4541

4642

4743
[<Unverifiable>]
48-
[<NoDynamicInvocation>]
4944
[<CompiledName("AddPointerInlined")>]
5045
/// <summary>Returns a typed native pointer by adding index * sizeof&lt;'T&gt; to the
5146
/// given input pointer.</summary>
@@ -55,7 +50,6 @@ namespace Microsoft.FSharp.NativeInterop
5550
val inline add : address:nativeptr<'T> -> index:int -> nativeptr<'T>
5651

5752
[<Unverifiable>]
58-
[<NoDynamicInvocation>]
5953
[<CompiledName("GetPointerInlined")>]
6054
/// <summary>Dereferences the typed native pointer computed by adding index * sizeof&lt;'T&gt; to the
6155
/// given input pointer.</summary>
@@ -65,23 +59,20 @@ namespace Microsoft.FSharp.NativeInterop
6559
val inline get : address:nativeptr<'T> -> index:int -> 'T
6660

6761
[<Unverifiable>]
68-
[<NoDynamicInvocation>]
6962
[<CompiledName("ReadPointerInlined")>]
7063
/// <summary>Dereferences the given typed native pointer.</summary>
7164
/// <param name="address">The input pointer.</param>
7265
/// <returns>The value at the pointer address.</returns>
7366
val inline read : address:nativeptr<'T> -> 'T
7467

7568
[<Unverifiable>]
76-
[<NoDynamicInvocation>]
7769
[<CompiledName("WritePointerInlined")>]
7870
/// <summary>Assigns the <c>value</c> into the memory location referenced by the given typed native pointer.</summary>
7971
/// <param name="address">The input pointer.</param>
8072
/// <param name="value">The value to assign.</param>
8173
val inline write : address:nativeptr<'T> -> value:'T -> unit
8274

8375
[<Unverifiable>]
84-
[<NoDynamicInvocation>]
8576
[<CompiledName("SetPointerInlined")>]
8677
/// <summary>Assigns the <c>value</c> into the memory location referenced by the typed native
8778
/// pointer computed by adding index * sizeof&lt;'T&gt; to the given input pointer.</summary>
@@ -94,14 +85,12 @@ namespace Microsoft.FSharp.NativeInterop
9485
/// <param name="count">The number of objects of type T to allocate.</param>
9586
/// <returns>A typed pointer to the allocated memory.</returns>
9687
[<Unverifiable>]
97-
[<NoDynamicInvocation>]
9888
[<CompiledName("StackAllocate")>]
9989
val inline stackalloc : count:int -> nativeptr<'T>
10090

10191
/// <summary>Converts a given typed native pointer to a managed pointer.</summary>
10292
/// <param name="address">The input pointer.</param>
10393
/// <returns>The managed pointer.</returns>
10494
[<Unverifiable>]
105-
[<NoDynamicInvocation>]
10695
[<CompiledName("ToByRefInlined")>]
10796
val inline toByRef : nativeptr<'T> -> byref<'T>

0 commit comments

Comments
 (0)