Skip to content

Commit

Permalink
Merge branch 'main' into better-error-reporting-yield
Browse files Browse the repository at this point in the history
  • Loading branch information
edgarfgp authored Oct 4, 2024
2 parents f278c63 + b187b80 commit 21e2acd
Show file tree
Hide file tree
Showing 50 changed files with 1,564 additions and 774 deletions.
3 changes: 3 additions & 0 deletions .fantomasignore
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,9 @@ src/Compiler/Facilities/AsyncMemoize.fsi
src/Compiler/Facilities/AsyncMemoize.fs
src/Compiler/AbstractIL/il.fs

src/Compiler/Driver/GraphChecking/Graph.fsi
src/Compiler/Driver/GraphChecking/Graph.fs

# Fantomas limitations on implementation files (to investigate)

src/Compiler/AbstractIL/ilwrite.fs
Expand Down
3 changes: 2 additions & 1 deletion docs/release-notes/.FSharp.Compiler.Service/9.0.200.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
### Fixed

* Fix false negatives for passing null to "obj" arguments. Only "obj | null" can now subsume any type ([PR #17757](https://github.com/dotnet/fsharp/pull/17757))
* Fix internal error when calling 'AddSingleton' and other overloads only differing in generic arity ([PR #17804](https://github.com/dotnet/fsharp/pull/17804))
* Fix extension methods support for non-reference system assemblies ([PR #17799](https://github.com/dotnet/fsharp/pull/17799))
* Ensure `frameworkTcImportsCache` mutations are thread-safe. ([PR #17795](https://github.com/dotnet/fsharp/pull/17795))
* Fix concurrency issue in `ILPreTypeDefImpl` ([PR #17812](https://github.com/dotnet/fsharp/pull/17812))


### Added

* Support literal attribute on decimals ([PR #17769](https://github.com/dotnet/fsharp/pull/17769))

### Changed

Expand Down
2 changes: 1 addition & 1 deletion src/Compiler/AbstractIL/ilreflect.fs
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ type TypeBuilder with

match m with
| null -> raise (MissingMethodException nm)
| m -> m.Invoke(null, args)
| m -> m.Invoke(null, (args: obj array))

member typB.SetCustomAttributeAndLog(cinfo, bytes) =
if logRefEmitCalls then
Expand Down
4 changes: 2 additions & 2 deletions src/Compiler/Checking/AttributeChecking.fs
Original file line number Diff line number Diff line change
Expand Up @@ -466,9 +466,9 @@ let MethInfoIsUnseen g (m: range) (ty: TType) minfo =

let isUnseenByHidingAttribute () =
#if !NO_TYPEPROVIDERS
not (isObjTy g ty) &&
not (isObjTyAnyNullness g ty) &&
isAppTy g ty &&
isObjTy g minfo.ApparentEnclosingType &&
isObjTyAnyNullness g minfo.ApparentEnclosingType &&
let tcref = tcrefOfAppTy g ty
match tcref.TypeReprInfo with
| TProvidedTypeRepr info ->
Expand Down
1,287 changes: 650 additions & 637 deletions src/Compiler/Checking/ConstraintSolver.fs

Large diffs are not rendered by default.

10 changes: 5 additions & 5 deletions src/Compiler/Checking/Expressions/CheckExpressions.fs
Original file line number Diff line number Diff line change
Expand Up @@ -3283,7 +3283,7 @@ let AnalyzeArbitraryExprAsEnumerable (cenv: cenv) (env: TcEnv) localAlloc m expr

let enumElemTy =

if isObjTy g enumElemTy then
if isObjTyAnyNullness g enumElemTy then
// Look for an 'Item' property, or a set of these with consistent return types
let allEquivReturnTypes (minfo: MethInfo) (others: MethInfo list) =
let returnTy = minfo.GetFSharpReturnType(cenv.amap, m, [])
Expand Down Expand Up @@ -6195,7 +6195,7 @@ and TcExprObjectExpr (cenv: cenv) overallTy env tpenv (synObjTy, argopt, binds,
errorR(Error(FSComp.SR.tcCannotInheritFromErasedType(), m))
(m, intfTy, overrides), tpenv)

let realObjTy = if isObjTy g objTy && not (isNil extraImpls) then (p23 (List.head extraImpls)) else objTy
let realObjTy = if isObjTyAnyNullness g objTy && not (isNil extraImpls) then (p23 (List.head extraImpls)) else objTy

TcPropagatingExprLeafThenConvert cenv overallTy realObjTy env (* canAdhoc *) m (fun () ->
TcObjectExpr cenv env tpenv (objTy, realObjTy, argopt, binds, extraImpls, mObjTy, mNewExpr, m)
Expand Down Expand Up @@ -7320,7 +7320,7 @@ and TcFormatStringExpr cenv (overallTy: OverallTy) env m tpenv (fmtString: strin
let formatTy = mkPrintfFormatTy g aty bty cty dty ety

// This might qualify as a format string - check via a type directed rule
let ok = not (isObjTy g overallTy.Commit) && AddCxTypeMustSubsumeTypeUndoIfFailed env.DisplayEnv cenv.css m overallTy.Commit formatTy
let ok = not (isObjTyAnyNullness g overallTy.Commit) && AddCxTypeMustSubsumeTypeUndoIfFailed env.DisplayEnv cenv.css m overallTy.Commit formatTy

if ok then
// Parse the format string to work out the phantom types
Expand Down Expand Up @@ -7399,7 +7399,7 @@ and TcInterpolatedStringExpr cenv (overallTy: OverallTy) env m tpenv (parts: Syn
Choice1Of2 (true, newFormatMethod)

// ... or if that fails then may be a FormattableString by a type-directed rule....
elif (not (isObjTy g overallTy.Commit) &&
elif (not (isObjTyAnyNullness g overallTy.Commit) &&
((g.system_FormattableString_tcref.CanDeref && AddCxTypeMustSubsumeTypeUndoIfFailed env.DisplayEnv cenv.css m overallTy.Commit g.system_FormattableString_ty)
|| (g.system_IFormattable_tcref.CanDeref && AddCxTypeMustSubsumeTypeUndoIfFailed env.DisplayEnv cenv.css m overallTy.Commit g.system_IFormattable_ty))) then

Expand All @@ -7420,7 +7420,7 @@ and TcInterpolatedStringExpr cenv (overallTy: OverallTy) env m tpenv (parts: Syn
| None -> languageFeatureNotSupportedInLibraryError LanguageFeature.StringInterpolation m

// ... or if that fails then may be a PrintfFormat by a type-directed rule....
elif not (isObjTy g overallTy.Commit) && AddCxTypeMustSubsumeTypeUndoIfFailed env.DisplayEnv cenv.css m overallTy.Commit formatTy then
elif not (isObjTyAnyNullness g overallTy.Commit) && AddCxTypeMustSubsumeTypeUndoIfFailed env.DisplayEnv cenv.css m overallTy.Commit formatTy then

// And if that succeeds, the printerTy and printerResultTy must be the same (there are no curried arguments)
UnifyTypes cenv env m printerTy printerResultTy
Expand Down
2 changes: 1 addition & 1 deletion src/Compiler/Checking/InfoReader.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1082,7 +1082,7 @@ let TryDestStandardDelegateType (infoReader: InfoReader) m ad delTy =
let g = infoReader.g
let (SigOfFunctionForDelegate(_, delArgTys, delRetTy, _)) = GetSigOfFunctionForDelegate infoReader delTy m ad
match delArgTys with
| senderTy :: argTys when (isObjTy g senderTy) && not (List.exists (isByrefTy g) argTys) -> Some(mkRefTupledTy g argTys, delRetTy)
| senderTy :: argTys when (isObjTyAnyNullness g senderTy) && not (List.exists (isByrefTy g) argTys) -> Some(mkRefTupledTy g argTys, delRetTy)
| _ -> None


Expand Down
2 changes: 1 addition & 1 deletion src/Compiler/Checking/MethodCalls.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1319,7 +1319,7 @@ let BuildNewDelegateExpr (eventInfoOpt: EventInfo option, g, amap, delegateTy, d
| Some einfo ->
match delArgVals with
| [] -> error(nonStandardEventError einfo.EventName m)
| h :: _ when not (isObjTy g h.Type) -> error(nonStandardEventError einfo.EventName m)
| h :: _ when not (isObjTyAnyNullness g h.Type) -> error(nonStandardEventError einfo.EventName m)
| h :: t -> [exprForVal m h; mkRefTupledVars g m t]
| None ->
if isNil delArgTys then [mkUnit g m] else List.map (exprForVal m) delArgVals
Expand Down
16 changes: 8 additions & 8 deletions src/Compiler/Checking/NameResolution.fs
Original file line number Diff line number Diff line change
Expand Up @@ -4422,14 +4422,14 @@ let ResolveCompletionsInType (ncenv: NameResolver) nenv (completionTargets: Reso
//
// Don't show GetHashCode or Equals for F# types that admit equality as an abnormal operation
let isUnseenDueToBasicObjRules =
not (isObjTy g ty) &&
not (isObjTyAnyNullness g ty) &&
not minfo.IsExtensionMember &&
match minfo.LogicalName with
| "GetType" -> false
| "GetHashCode" -> isObjTy g minfo.ApparentEnclosingType && not (AugmentTypeDefinitions.TypeDefinitelyHasEquality g ty)
| "GetHashCode" -> isObjTyAnyNullness g minfo.ApparentEnclosingType && not (AugmentTypeDefinitions.TypeDefinitelyHasEquality g ty)
| "ToString" -> false
| "Equals" ->
if not (isObjTy g minfo.ApparentEnclosingType) then
if not (isObjTyAnyNullness g minfo.ApparentEnclosingType) then
// declaring type is not System.Object - show it
false
elif minfo.IsInstance then
Expand All @@ -4440,7 +4440,7 @@ let ResolveCompletionsInType (ncenv: NameResolver) nenv (completionTargets: Reso
true
| _ ->
// filter out self methods of obj type
isObjTy g minfo.ApparentEnclosingType
isObjTyAnyNullness g minfo.ApparentEnclosingType

let result =
not isUnseenDueToBasicObjRules &&
Expand Down Expand Up @@ -5121,14 +5121,14 @@ let ResolveCompletionsInTypeForItem (ncenv: NameResolver) nenv m ad statics ty (
//
// Don't show GetHashCode or Equals for F# types that admit equality as an abnormal operation
let isUnseenDueToBasicObjRules =
not (isObjTy g ty) &&
not (isObjTyAnyNullness g ty) &&
not minfo.IsExtensionMember &&
match minfo.LogicalName with
| "GetType" -> false
| "GetHashCode" -> isObjTy g minfo.ApparentEnclosingType && not (AugmentTypeDefinitions.TypeDefinitelyHasEquality g ty)
| "GetHashCode" -> isObjTyAnyNullness g minfo.ApparentEnclosingType && not (AugmentTypeDefinitions.TypeDefinitelyHasEquality g ty)
| "ToString" -> false
| "Equals" ->
if not (isObjTy g minfo.ApparentEnclosingType) then
if not (isObjTyAnyNullness g minfo.ApparentEnclosingType) then
// declaring type is not System.Object - show it
false
elif minfo.IsInstance then
Expand All @@ -5139,7 +5139,7 @@ let ResolveCompletionsInTypeForItem (ncenv: NameResolver) nenv m ad statics ty (
true
| _ ->
// filter out self methods of obj type
isObjTy g minfo.ApparentEnclosingType
isObjTyAnyNullness g minfo.ApparentEnclosingType
let result =
not isUnseenDueToBasicObjRules &&
not minfo.IsInstance = statics &&
Expand Down
2 changes: 1 addition & 1 deletion src/Compiler/Checking/NicePrint.fs
Original file line number Diff line number Diff line change
Expand Up @@ -2191,7 +2191,7 @@ module TastDefinitionPrinting =
let inherits =
[ if not (suppressInheritanceAndInterfacesForTyInSimplifiedDisplays g amap m ty) then
match GetSuperTypeOfType g amap m ty with
| Some superTy when not (isObjTy g superTy) && not (isValueTypeTy g superTy) ->
| Some superTy when not (isObjTyAnyNullness g superTy) && not (isValueTypeTy g superTy) ->
superTy
| _ -> ()
]
Expand Down
3 changes: 2 additions & 1 deletion src/Compiler/Checking/PostInferenceChecks.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1958,7 +1958,8 @@ and CheckAttribArgExpr cenv env expr =
| Const.Single _
| Const.Char _
| Const.Zero
| Const.String _ -> ()
| Const.String _
| Const.Decimal _ -> ()
| _ ->
if cenv.reportErrors then
errorR (Error (FSComp.SR.tastNotAConstantExpression(), m))
Expand Down
2 changes: 1 addition & 1 deletion src/Compiler/Checking/TypeHierarchy.fs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ let GetSuperTypeOfType g amap m ty =
Some (instType (mkInstForAppTy g ty) (superOfTycon g tcref.Deref))
elif isArrayTy g ty then
Some g.system_Array_ty
elif isRefTy g ty && not (isObjTy g ty) then
elif isRefTy g ty && not (isObjTyAnyNullness g ty) then
Some g.obj_ty_noNulls
elif isStructTupleTy g ty then
Some g.system_Value_ty
Expand Down
2 changes: 1 addition & 1 deletion src/Compiler/Checking/TypeRelations.fs
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ let rec TypeFeasiblySubsumesType ndeep g amap m ty1 canCoerce ty2 =

| _ ->
// F# reference types are subtypes of type 'obj'
(isObjTy g ty1 && (canCoerce = CanCoerce || isRefTy g ty2))
(isObjTyAnyNullness g ty1 && (canCoerce = CanCoerce || isRefTy g ty2))
||
(isAppTy g ty2 &&
(canCoerce = CanCoerce || isRefTy g ty2) &&
Expand Down
10 changes: 6 additions & 4 deletions src/Compiler/Checking/infos.fs
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ type OptionalArgInfo =
if isByrefTy g ty then
let ty = destByrefTy g ty
PassByRef (ty, analyze ty)
elif isObjTy g ty then
elif isObjTyAnyNullness g ty then
match ilParam.Marshal with
| Some(ILNativeType.IUnknown | ILNativeType.IDispatch | ILNativeType.Interface) -> Constant ILFieldInit.Null
| _ ->
Expand Down Expand Up @@ -296,7 +296,7 @@ let CrackParamAttribsInfo g (ty: TType, argInfo: ArgReprInfo) =
| None ->
// Do a type-directed analysis of the type to determine the default value to pass.
// Similar rules as OptionalArgInfo.FromILParameter are applied here, except for the COM and byref-related stuff.
CallerSide (if isObjTy g ty then MissingValue else DefaultValue)
CallerSide (if isObjTyAnyNullness g ty then MissingValue else DefaultValue)
| Some attr ->
let defaultValue = OptionalArgInfo.ValueOfDefaultParameterValueAttrib attr
match defaultValue with
Expand Down Expand Up @@ -364,7 +364,9 @@ type ILFieldInit with
| :? uint32 as i -> ILFieldInit.UInt32 i
| :? int64 as i -> ILFieldInit.Int64 i
| :? uint64 as i -> ILFieldInit.UInt64 i
| _ -> error(Error(FSComp.SR.infosInvalidProvidedLiteralValue(try !!v.ToString() with _ -> "?"), m))
| _ ->
let txt = match v with | null -> "?" | v -> try !!v.ToString() with _ -> "?"
error(Error(FSComp.SR.infosInvalidProvidedLiteralValue(txt), m))


/// Compute the OptionalArgInfo for a provided parameter.
Expand All @@ -382,7 +384,7 @@ let OptionalArgInfoOfProvidedParameter (amap: ImportMap) m (provParam : Tainted<
if isByrefTy g ty then
let ty = destByrefTy g ty
PassByRef (ty, analyze ty)
elif isObjTy g ty then MissingValue
elif isObjTyAnyNullness g ty then MissingValue
else DefaultValue

let paramTy = ImportProvidedType amap m (provParam.PApply((fun p -> p.ParameterType), m))
Expand Down
74 changes: 69 additions & 5 deletions src/Compiler/CodeGen/IlxGen.fs
Original file line number Diff line number Diff line change
Expand Up @@ -3782,11 +3782,11 @@ and GenCoerce cenv cgbuf eenv (e, tgtTy, m, srcTy) sequel =
else
GenExpr cenv cgbuf eenv e Continue

if not (isObjTy g srcTy) then
if not (isObjTyAnyNullness g srcTy) then
let ilFromTy = GenType cenv m eenv.tyenv srcTy
CG.EmitInstr cgbuf (pop 1) (Push [ g.ilg.typ_Object ]) (I_box ilFromTy)

if not (isObjTy g tgtTy) then
if not (isObjTyAnyNullness g tgtTy) then
let ilToTy = GenType cenv m eenv.tyenv tgtTy
CG.EmitInstr cgbuf (pop 1) (Push [ ilToTy ]) (I_unbox_any ilToTy)

Expand Down Expand Up @@ -8563,10 +8563,15 @@ and GenBindingAfterDebugPoint cenv cgbuf eenv bind isStateVar startMarkOpt =

let ilFieldDef = mkILStaticField (fspec.Name, fty, None, None, access)

let isDecimalConstant =
match vref.LiteralValue with
| Some(Const.Decimal _) -> true
| _ -> false

let ilFieldDef =
match vref.LiteralValue with
| Some konst -> ilFieldDef.WithLiteralDefaultValue(Some(GenFieldInit m konst))
| None -> ilFieldDef
| Some konst when not isDecimalConstant -> ilFieldDef.WithLiteralDefaultValue(Some(GenFieldInit m konst))
| _ -> ilFieldDef

let ilFieldDef =
let isClassInitializer = (cgbuf.MethodName = ".cctor")
Expand All @@ -8578,6 +8583,7 @@ and GenBindingAfterDebugPoint cenv cgbuf eenv bind isStateVar startMarkOpt =
|| not isClassInitializer
|| hasLiteralAttr
)
|| isDecimalConstant
)

let ilAttribs =
Expand All @@ -8590,6 +8596,64 @@ and GenBindingAfterDebugPoint cenv cgbuf eenv bind isStateVar startMarkOpt =

let ilAttribs = GenAdditionalAttributesForTy g vspec.Type @ ilAttribs

let ilAttribs =
if isDecimalConstant then
match vref.LiteralValue with
| Some(Const.Decimal d) ->
match System.Decimal.GetBits d with
| [| lo; med; hi; signExp |] ->
let scale = (min (((signExp &&& 0xFF0000) >>> 16) &&& 0xFF) 28) |> byte
let sign = if (signExp &&& 0x80000000) <> 0 then 1uy else 0uy

let attrib =
mkILCustomAttribute (
g.attrib_DecimalConstantAttribute.TypeRef,
[
g.ilg.typ_Byte
g.ilg.typ_Byte
g.ilg.typ_Int32
g.ilg.typ_Int32
g.ilg.typ_Int32
],
[
ILAttribElem.Byte scale
ILAttribElem.Byte sign
ILAttribElem.UInt32(uint32 hi)
ILAttribElem.UInt32(uint32 med)
ILAttribElem.UInt32(uint32 lo)
],
[]
)

let ilInstrs =
[
mkLdcInt32 lo
mkLdcInt32 med
mkLdcInt32 hi
mkLdcInt32 (int32 sign)
mkLdcInt32 (int32 scale)
mkNormalNewobj (
mkILCtorMethSpecForTy (
fspec.ActualType,
[
g.ilg.typ_Int32
g.ilg.typ_Int32
g.ilg.typ_Int32
g.ilg.typ_Bool
g.ilg.typ_Byte
]
)
)
mkNormalStsfld fspec
]

CG.EmitInstrs cgbuf (pop 0) (Push0) ilInstrs
[ attrib ]
| _ -> failwith "unreachable"
| _ -> failwith "unreachable"
else
ilAttribs

let ilFieldDef =
ilFieldDef.With(customAttrs = mkILCustomAttrs (ilAttribs @ [ g.DebuggerBrowsableNeverAttribute ]))

Expand Down Expand Up @@ -12118,7 +12182,7 @@ let LookupGeneratedValue (cenv: cenv) (ctxt: ExecutionContext) eenv (v: Val) =
None

// Invoke the set_Foo method for a declaration with a value. Used to create variables with values programmatically in fsi.exe.
let SetGeneratedValue (ctxt: ExecutionContext) eenv isForced (v: Val) (value: obj) =
let SetGeneratedValue (ctxt: ExecutionContext) eenv isForced (v: Val) (value: objnull) =
try
match StorageForVal v.Range v eenv with
| StaticPropertyWithField(fspec, _, hasLiteralAttr, _, _, _, _f, ilSetterMethRef, _) ->
Expand Down
Loading

0 comments on commit 21e2acd

Please sign in to comment.