Skip to content

Commit d78f5aa

Browse files
authored
Feature nullness :: warn also for 'obj' type (since it can be infered for null literal) (#16962)
1 parent 42c6afd commit d78f5aa

19 files changed

+124
-81
lines changed

src/Compiler/Checking/AugmentWithHashCompare.fs

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ open FSharp.Compiler.TypedTreeOps
1515
open FSharp.Compiler.TypeHierarchy
1616

1717
let mkIComparableCompareToSlotSig (g: TcGlobals) =
18-
TSlotSig("CompareTo", g.mk_IComparable_ty, [], [], [ [ TSlotParam(Some("obj"), g.obj_ty, false, false, false, []) ] ], Some g.int_ty)
18+
TSlotSig("CompareTo", g.mk_IComparable_ty, [], [], [ [ TSlotParam(Some("obj"), g.obj_ty_withNulls, false, false, false, []) ] ], Some g.int_ty)
1919

2020
let mkGenericIComparableCompareToSlotSig (g: TcGlobals) ty =
2121
TSlotSig(
@@ -35,7 +35,7 @@ let mkIStructuralComparableCompareToSlotSig (g: TcGlobals) =
3535
[],
3636
[
3737
[
38-
TSlotParam(None, (mkRefTupledTy g [ g.obj_ty; g.IComparer_ty ]), false, false, false, [])
38+
TSlotParam(None, (mkRefTupledTy g [ g.obj_ty_withNulls; g.IComparer_ty ]), false, false, false, [])
3939
]
4040
],
4141
Some g.int_ty
@@ -59,7 +59,7 @@ let mkIStructuralEquatableEqualsSlotSig (g: TcGlobals) =
5959
[],
6060
[
6161
[
62-
TSlotParam(None, (mkRefTupledTy g [ g.obj_ty; g.IEqualityComparer_ty ]), false, false, false, [])
62+
TSlotParam(None, (mkRefTupledTy g [ g.obj_ty_withNulls; g.IEqualityComparer_ty ]), false, false, false, [])
6363
]
6464
],
6565
Some g.bool_ty
@@ -76,10 +76,10 @@ let mkIStructuralEquatableGetHashCodeSlotSig (g: TcGlobals) =
7676
)
7777

7878
let mkGetHashCodeSlotSig (g: TcGlobals) =
79-
TSlotSig("GetHashCode", g.obj_ty, [], [], [ [] ], Some g.int_ty)
79+
TSlotSig("GetHashCode", g.obj_ty_noNulls, [], [], [ [] ], Some g.int_ty)
8080

8181
let mkEqualsSlotSig (g: TcGlobals) =
82-
TSlotSig("Equals", g.obj_ty, [], [], [ [ TSlotParam(Some("obj"), g.obj_ty, false, false, false, []) ] ], Some g.bool_ty)
82+
TSlotSig("Equals", g.obj_ty_noNulls, [], [], [ [ TSlotParam(Some("obj"), g.obj_ty_withNulls, false, false, false, []) ] ], Some g.bool_ty)
8383

8484
//-------------------------------------------------------------------------
8585
// Helpers associated with code-generation of comparison/hash augmentations
@@ -89,22 +89,22 @@ let mkThisTy g ty =
8989
if isStructTy g ty then mkByrefTy g ty else ty
9090

9191
let mkCompareObjTy g ty =
92-
mkFunTy g (mkThisTy g ty) (mkFunTy g g.obj_ty g.int_ty)
92+
mkFunTy g (mkThisTy g ty) (mkFunTy g g.obj_ty_withNulls g.int_ty)
9393

9494
let mkCompareTy g ty =
9595
mkFunTy g (mkThisTy g ty) (mkFunTy g ty g.int_ty)
9696

9797
let mkCompareWithComparerTy g ty =
98-
mkFunTy g (mkThisTy g ty) (mkFunTy g (mkRefTupledTy g [ g.obj_ty; g.IComparer_ty ]) g.int_ty)
98+
mkFunTy g (mkThisTy g ty) (mkFunTy g (mkRefTupledTy g [ g.obj_ty_withNulls; g.IComparer_ty ]) g.int_ty)
9999

100100
let mkEqualsObjTy g ty =
101-
mkFunTy g (mkThisTy g ty) (mkFunTy g g.obj_ty g.bool_ty)
101+
mkFunTy g (mkThisTy g ty) (mkFunTy g g.obj_ty_withNulls g.bool_ty)
102102

103103
let mkEqualsTy g ty =
104104
mkFunTy g (mkThisTy g ty) (mkFunTy g ty g.bool_ty)
105105

106106
let mkEqualsWithComparerTy g ty =
107-
mkFunTy g (mkThisTy g ty) (mkFunTy g (mkRefTupledTy g [ g.obj_ty; g.IEqualityComparer_ty ]) g.bool_ty)
107+
mkFunTy g (mkThisTy g ty) (mkFunTy g (mkRefTupledTy g [ g.obj_ty_withNulls; g.IEqualityComparer_ty ]) g.bool_ty)
108108

109109
let mkHashTy g ty =
110110
mkFunTy g (mkThisTy g ty) (mkFunTy g g.unit_ty g.int_ty)
@@ -1096,7 +1096,7 @@ let CheckAugmentationAttribs isImplementation g amap (tycon: Tycon) =
10961096
hasNominalInterface g.system_GenericIComparable_tcref
10971097

10981098
let hasExplicitEquals =
1099-
tycon.HasOverride g "Equals" [ g.obj_ty ]
1099+
tycon.HasOverride g "Equals" [ g.obj_ty_ambivalent ]
11001100
|| hasNominalInterface g.tcref_System_IStructuralEquatable
11011101

11021102
let hasExplicitGenericEquals = hasNominalInterface g.system_GenericIEquatable_tcref
@@ -1351,13 +1351,13 @@ let MakeBindingsForCompareAugmentation g (tycon: Tycon) =
13511351
let tinst, ty = mkMinimalTy g tcref
13521352

13531353
let thisv, thise = mkThisVar g m ty
1354-
let thatobjv, thatobje = mkCompGenLocal m "obj" g.obj_ty
1354+
let thatobjv, thatobje = mkCompGenLocal m "obj" g.obj_ty_ambivalent
13551355

13561356
let comparee =
13571357
if isUnitTy g ty then
13581358
mkZero g m
13591359
else
1360-
let thate = mkCoerceExpr (thatobje, ty, m, g.obj_ty)
1360+
let thate = mkCoerceExpr (thatobje, ty, m, g.obj_ty_ambivalent)
13611361

13621362
mkApps g ((exprForValRef m vref2, vref2.Type), (if isNil tinst then [] else [ tinst ]), [ thise; thate ], m)
13631363

@@ -1394,8 +1394,8 @@ let MakeBindingsForCompareWithComparerAugmentation g (tycon: Tycon) =
13941394
let compv, compe = mkCompGenLocal m "comp" g.IComparer_ty
13951395

13961396
let thisv, thise = mkThisVar g m ty
1397-
let thatobjv, thatobje = mkCompGenLocal m "obj" g.obj_ty
1398-
let thate = mkCoerceExpr (thatobje, ty, m, g.obj_ty)
1397+
let thatobjv, thatobje = mkCompGenLocal m "obj" g.obj_ty_ambivalent
1398+
let thate = mkCoerceExpr (thatobje, ty, m, g.obj_ty_ambivalent)
13991399

14001400
let rhs =
14011401
let comparee = comparef g tcref tycon (thisv, thise) (thatobjv, thate) compe
@@ -1453,7 +1453,7 @@ let MakeBindingsForEqualityWithComparerAugmentation (g: TcGlobals) (tycon: Tycon
14531453
let withcEqualsExpr =
14541454
let _tinst, ty = mkMinimalTy g tcref
14551455
let thisv, thise = mkThisVar g m ty
1456-
let thatobjv, thatobje = mkCompGenLocal m "obj" g.obj_ty
1456+
let thatobjv, thatobje = mkCompGenLocal m "obj" g.obj_ty_ambivalent
14571457
let thatv, thate = mkCompGenLocal m "that" ty
14581458
let compv, compe = mkCompGenLocal m "comp" g.IEqualityComparer_ty
14591459
let equalse = equalsf g tcref tycon (thisv, thise) thatobje (thatv, thate) compe
@@ -1515,7 +1515,7 @@ let MakeBindingsForEqualsAugmentation (g: TcGlobals) (tycon: Tycon) =
15151515
let tinst, ty = mkMinimalTy g tcref
15161516

15171517
let thisv, thise = mkThisVar g m ty
1518-
let thatobjv, thatobje = mkCompGenLocal m "obj" g.obj_ty
1518+
let thatobjv, thatobje = mkCompGenLocal m "obj" g.obj_ty_ambivalent
15191519

15201520
let equalse =
15211521
if isUnitTy g ty then

src/Compiler/Checking/CheckDeclarations.fs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -860,7 +860,7 @@ module AddAugmentationDeclarations =
860860
let m = tycon.Range
861861

862862
// Note: tycon.HasOverride only gives correct results after we've done the type augmentation
863-
let hasExplicitObjectEqualsOverride = tycon.HasOverride g "Equals" [g.obj_ty]
863+
let hasExplicitObjectEqualsOverride = tycon.HasOverride g "Equals" [g.obj_ty_ambivalent]
864864
let hasExplicitGenericIEquatable = tcaugHasNominalInterface g tcaug g.system_GenericIEquatable_tcref
865865

866866
if hasExplicitGenericIEquatable then
@@ -1610,7 +1610,7 @@ module MutRecBindingChecking =
16101610
if tcref.IsStructOrEnumTycon then
16111611
Some (incrCtorInfo, mkUnit g tcref.Range, false), defnCs
16121612
else
1613-
let inheritsExpr, _ = TcNewExpr cenv envForDecls tpenv g.obj_ty None true (SynExpr.Const (SynConst.Unit, tcref.Range)) tcref.Range
1613+
let inheritsExpr, _ = TcNewExpr cenv envForDecls tpenv g.obj_ty_noNulls None true (SynExpr.Const (SynConst.Unit, tcref.Range)) tcref.Range
16141614

16151615
// If there is no 'inherits' and no simple non-static 'let' of a non-method then add a debug point at the entry to the constructor over the type name itself.
16161616
let addDebugPointAtImplicitCtorArguments =
@@ -3313,7 +3313,7 @@ module EstablishTypeDefinitionCores =
33133313
if isTyparTy g ty then
33143314
if firstPass then
33153315
errorR(Error(FSComp.SR.tcCannotInheritFromVariableType(), m))
3316-
Some g.obj_ty // a "super" that is a variable type causes grief later
3316+
Some g.obj_ty_noNulls // a "super" that is a variable type causes grief later
33173317
else
33183318
Some ty
33193319
| _ ->

src/Compiler/Checking/CheckExpressions.fs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3106,7 +3106,7 @@ let BuildDisposableCleanup (cenv: cenv) env m (v: Val) =
31063106
else
31073107
let disposeObjVar, disposeObjExpr = mkCompGenLocal m "objectToDispose" g.system_IDisposable_ty
31083108
let disposeExpr, _ = BuildPossiblyConditionalMethodCall cenv env PossiblyMutates m false disposeMethod NormalValUse [] [disposeObjExpr] [] None
3109-
let inputExpr = mkCoerceExpr(exprForVal v.Range v, g.obj_ty, m, v.Type)
3109+
let inputExpr = mkCoerceExpr(exprForVal v.Range v, g.obj_ty_ambivalent, m, v.Type)
31103110
mkIsInstConditional g m g.system_IDisposable_ty inputExpr disposeObjVar disposeExpr (mkUnit g m)
31113111

31123112
/// Build call to get_OffsetToStringData as part of 'fixed'
@@ -3346,7 +3346,7 @@ let AnalyzeArbitraryExprAsEnumerable (cenv: cenv) (env: TcEnv) localAlloc m expr
33463346
// e.g. MatchCollection
33473347
typeEquiv g g.int32_ty ty ||
33483348
// e.g. EnvDTE.Documents.Item
3349-
typeEquiv g g.obj_ty ty
3349+
typeEquiv g g.obj_ty_ambivalent ty
33503350
| _ -> false
33513351

33523352
match TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AllResults cenv env m ad "get_Item" tyToSearchForGetEnumeratorAndItem with
@@ -4462,7 +4462,7 @@ and TcTypeOrMeasure kindOpt (cenv: cenv) newOk checkConstraints occ (iwsam: Warn
44624462
match synTy with
44634463
| SynType.LongIdent(SynLongIdent([], _, _)) ->
44644464
// special case when type name is absent - i.e. empty inherit part in type declaration
4465-
g.obj_ty, tpenv
4465+
g.obj_ty_ambivalent, tpenv
44664466

44674467
| SynType.LongIdent synLongId ->
44684468
TcLongIdentType kindOpt cenv newOk checkConstraints occ iwsam env tpenv synLongId
@@ -5096,7 +5096,7 @@ and TcTypeOrMeasureAndRecover kindOpt (cenv: cenv) newOk checkConstraints occ iw
50965096
match kindOpt, newOk with
50975097
| Some TyparKind.Measure, NoNewTypars -> TType_measure Measure.One
50985098
| Some TyparKind.Measure, _ -> TType_measure (NewErrorMeasure ())
5099-
| _, NoNewTypars -> g.obj_ty
5099+
| _, NoNewTypars -> g.obj_ty_ambivalent
51005100
| _ -> NewErrorType ()
51015101

51025102
recoveryTy, tpenv
@@ -7482,7 +7482,7 @@ and TcInterpolatedStringExpr cenv (overallTy: OverallTy) env m tpenv (parts: Syn
74827482

74837483
let fillExprsBoxed = (argTys, fillExprs) ||> List.map2 (mkCallBox g m)
74847484

7485-
let argsExpr = mkArray (g.obj_ty, fillExprsBoxed, m)
7485+
let argsExpr = mkArray (g.obj_ty_withNulls, fillExprsBoxed, m)
74867486
let percentATysExpr =
74877487
if percentATys.Length = 0 then
74887488
mkNull m (mkArrayType g g.system_Type_ty)
@@ -7509,7 +7509,7 @@ and TcInterpolatedStringExpr cenv (overallTy: OverallTy) env m tpenv (parts: Syn
75097509
let fillExprsBoxed = (argTys, fillExprs) ||> List.map2 (mkCallBox g m)
75107510

75117511
let dotnetFormatStringExpr = mkString g m dotnetFormatString
7512-
let argsExpr = mkArray (g.obj_ty, fillExprsBoxed, m)
7512+
let argsExpr = mkArray (g.obj_ty_withNulls, fillExprsBoxed, m)
75137513

75147514
// FormattableString are *always* turned into FormattableStringFactory.Create calls, boxing each argument
75157515
let createExpr, _ = BuildPossiblyConditionalMethodCall cenv env NeverMutates m false createFormattableStringMethod NormalValUse [] [dotnetFormatStringExpr; argsExpr] [] None
@@ -9540,7 +9540,7 @@ and TcEventItemThen (cenv: cenv) overallTy env tpenv mItem mExprAndItem objDetai
95409540
(let dv, de = mkCompGenLocal mItem "eventDelegate" delTy
95419541
let callExpr, _ = BuildPossiblyConditionalMethodCall cenv env PossiblyMutates mItem false einfo.RemoveMethod NormalValUse [] objVars [de] None
95429542
mkLambda mItem dv (callExpr, g.unit_ty))
9543-
(let fvty = mkFunTy g g.obj_ty (mkFunTy g argsTy g.unit_ty)
9543+
(let fvty = mkFunTy g g.obj_ty_withNulls (mkFunTy g argsTy g.unit_ty)
95449544
let fv, fe = mkCompGenLocal mItem "callback" fvty
95459545
let createExpr = BuildNewDelegateExpr (Some einfo, g, cenv.amap, delTy, delInvokeMeth, delArgTys, fe, fvty, mItem)
95469546
mkLambda mItem fv (createExpr, delTy)))
@@ -9926,7 +9926,7 @@ and TcAdhocChecksOnLibraryMethods (cenv: cenv) (env: TcEnv) isInstance (finalCal
99269926

99279927
if (isInstance &&
99289928
finalCalledMethInfo.IsInstance &&
9929-
typeEquiv g finalCalledMethInfo.ApparentEnclosingType g.obj_ty &&
9929+
typeEquiv g finalCalledMethInfo.ApparentEnclosingType g.obj_ty_ambivalent &&
99309930
(finalCalledMethInfo.LogicalName = "GetHashCode" || finalCalledMethInfo.LogicalName = "Equals")) then
99319931

99329932
for objArg in objArgs do

src/Compiler/Checking/ConstraintSolver.fs

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1050,12 +1050,8 @@ and SolveNullnessEquiv (csenv: ConstraintSolverEnv) m2 (trace: OptionalTrace) ty
10501050
// TODO NULLNESS: this is not sound in contravariant cases etc. It is assuming covariance.
10511051
| NullnessInfo.WithNull, NullnessInfo.WithoutNull -> CompleteD
10521052
| _ ->
1053-
// NOTE: we never give nullness warnings for the 'obj' type
10541053
if csenv.g.checkNullness then
1055-
if not (isObjTy csenv.g ty1) || not (isObjTy csenv.g ty2) then
1056-
WarnD(ConstraintSolverNullnessWarningEquivWithTypes(csenv.DisplayEnv, ty1, ty2, n1, n2, csenv.m, m2))
1057-
else
1058-
CompleteD
1054+
WarnD(ConstraintSolverNullnessWarningEquivWithTypes(csenv.DisplayEnv, ty1, ty2, n1, n2, csenv.m, m2))
10591055
else
10601056
CompleteD
10611057

@@ -1088,11 +1084,8 @@ and SolveNullnessSubsumesNullness (csenv: ConstraintSolverEnv) m2 (trace: Option
10881084
| NullnessInfo.WithNull, NullnessInfo.WithoutNull ->
10891085
CompleteD
10901086
| NullnessInfo.WithoutNull, NullnessInfo.WithNull ->
1091-
if csenv.g.checkNullness then
1092-
if not (isObjTy csenv.g ty1) || not (isObjTy csenv.g ty2) then
1093-
WarnD(ConstraintSolverNullnessWarningWithTypes(csenv.DisplayEnv, ty1, ty2, n1, n2, csenv.m, m2))
1094-
else
1095-
CompleteD
1087+
if csenv.g.checkNullness then
1088+
WarnD(ConstraintSolverNullnessWarningWithTypes(csenv.DisplayEnv, ty1, ty2, n1, n2, csenv.m, m2))
10961089
else
10971090
CompleteD
10981091

@@ -2575,7 +2568,7 @@ and SolveNullnessSupportsNull (csenv: ConstraintSolverEnv) ndeep m2 (trace: Opti
25752568
| NullnessInfo.AmbivalentToNull -> ()
25762569
| NullnessInfo.WithNull -> ()
25772570
| NullnessInfo.WithoutNull ->
2578-
if g.checkNullness && not (isObjTy g ty) then
2571+
if g.checkNullness then
25792572
return! WarnD(ConstraintSolverNullnessWarningWithType(denv, ty, n1, m, m2))
25802573
}
25812574

@@ -2590,7 +2583,7 @@ and SolveTypeUseNotSupportsNull (csenv: ConstraintSolverEnv) ndeep m2 trace ty =
25902583
// code via Option.ofObj and Option.toObj
25912584
do! WarnD (ConstraintSolverNullnessWarning(FSComp.SR.csTypeHasNullAsTrueValue(NicePrint.minimalStringOfType denv ty), m, m2))
25922585
elif TypeNullIsExtraValueNew g m ty then
2593-
if g.checkNullness && not (isObjTy g ty) then
2586+
if g.checkNullness then
25942587
let denv = { denv with showNullnessAnnotations = Some true }
25952588
do! WarnD (ConstraintSolverNullnessWarning(FSComp.SR.csTypeHasNullAsExtraValue(NicePrint.minimalStringOfType denv ty), m, m2))
25962589
else
@@ -2618,7 +2611,7 @@ and SolveNullnessNotSupportsNull (csenv: ConstraintSolverEnv) ndeep m2 (trace: O
26182611
| NullnessInfo.AmbivalentToNull -> ()
26192612
| NullnessInfo.WithoutNull -> ()
26202613
| NullnessInfo.WithNull ->
2621-
if g.checkNullness && TypeNullIsExtraValueNew g m ty && not (isObjTy g ty) then
2614+
if g.checkNullness && TypeNullIsExtraValueNew g m ty then
26222615
let denv = { denv with showNullnessAnnotations = Some true }
26232616
return! WarnD(ConstraintSolverNullnessWarning(FSComp.SR.csTypeHasNullAsExtraValue(NicePrint.minimalStringOfType denv ty), m, m2))
26242617
}

src/Compiler/Checking/MethodCalls.fs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1260,7 +1260,7 @@ let MethInfoChecks g amap isInstance tyargsOpt objArgs ad m (minfo: MethInfo) =
12601260
/// Build a call to the System.Object constructor taking no arguments,
12611261
let BuildObjCtorCall (g: TcGlobals) m =
12621262
let ilMethRef = (mkILCtorMethSpecForTy(g.ilg.typ_Object, [])).MethodRef
1263-
Expr.Op (TOp.ILCall (false, false, false, false, CtorValUsedAsSuperInit, false, true, ilMethRef, [], [], [g.obj_ty]), [], [], m)
1263+
Expr.Op (TOp.ILCall (false, false, false, false, CtorValUsedAsSuperInit, false, true, ilMethRef, [], [], [g.obj_ty_noNulls]), [], [], m)
12641264

12651265
/// Implements the elaborated form of adhoc conversions from functions to delegates at member callsites
12661266
let BuildNewDelegateExpr (eventInfoOpt: EventInfo option, g, amap, delegateTy, delInvokeMeth: MethInfo, delArgTys, delFuncExpr, delFuncTy, m) =
@@ -1447,7 +1447,7 @@ let rec GetDefaultExpressionForCallerSideOptionalArg tcFieldInit g (calledArg: C
14471447
| Some tref ->
14481448
let ty = mkILNonGenericBoxedTy tref
14491449
let mref = mkILCtorMethSpecForTy(ty, [g.ilg.typ_Object]).MethodRef
1450-
let expr = Expr.Op (TOp.ILCall (false, false, false, true, NormalValUse, false, false, mref, [], [], [g.obj_ty]), [], [mkDefault(mMethExpr, currCalledArgTy)], mMethExpr)
1450+
let expr = Expr.Op (TOp.ILCall (false, false, false, true, NormalValUse, false, false, mref, [], [], [g.obj_ty_noNulls]), [], [mkDefault(mMethExpr, currCalledArgTy)], mMethExpr)
14511451
emptyPreBinder, expr
14521452

14531453
| WrapperForIUnknown ->
@@ -1456,7 +1456,7 @@ let rec GetDefaultExpressionForCallerSideOptionalArg tcFieldInit g (calledArg: C
14561456
| Some tref ->
14571457
let ty = mkILNonGenericBoxedTy tref
14581458
let mref = mkILCtorMethSpecForTy(ty, [g.ilg.typ_Object]).MethodRef
1459-
let expr = Expr.Op (TOp.ILCall (false, false, false, true, NormalValUse, false, false, mref, [], [], [g.obj_ty]), [], [mkDefault(mMethExpr, currCalledArgTy)], mMethExpr)
1459+
let expr = Expr.Op (TOp.ILCall (false, false, false, true, NormalValUse, false, false, mref, [], [], [g.obj_ty_noNulls]), [], [mkDefault(mMethExpr, currCalledArgTy)], mMethExpr)
14601460
emptyPreBinder, expr
14611461

14621462
| PassByRef (ty, dfltVal2) ->

src/Compiler/Checking/MethodOverrides.fs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -897,7 +897,7 @@ let FinalTypeDefinitionChecksAtEndOfInferenceScope (infoReader: InfoReader, nenv
897897
#endif
898898
Option.isNone tycon.GeneratedCompareToValues &&
899899
tycon.HasInterface g g.mk_IComparable_ty &&
900-
not (tycon.HasOverride g "Equals" [g.obj_ty]) &&
900+
not (tycon.HasOverride g "Equals" [g.obj_ty_ambivalent]) &&
901901
not tycon.IsFSharpInterfaceTycon
902902
then
903903
(* Warn when we're doing this for class types *)
@@ -916,7 +916,7 @@ let FinalTypeDefinitionChecksAtEndOfInferenceScope (infoReader: InfoReader, nenv
916916
let tcaug = tycon.TypeContents
917917
let m = tycon.Range
918918
let hasExplicitObjectGetHashCode = tycon.HasOverride g "GetHashCode" []
919-
let hasExplicitObjectEqualsOverride = tycon.HasOverride g "Equals" [g.obj_ty]
919+
let hasExplicitObjectEqualsOverride = tycon.HasOverride g "Equals" [g.obj_ty_ambivalent]
920920

921921
if (Option.isSome tycon.GeneratedHashAndEqualsWithComparerValues) &&
922922
(hasExplicitObjectGetHashCode || hasExplicitObjectEqualsOverride) then

src/Compiler/Checking/NameResolution.fs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4017,7 +4017,7 @@ let ResolveNestedField sink (ncenv: NameResolver) nenv ad recdTy lid =
40174017
match item with
40184018
| Item.RecdField info -> info.FieldType
40194019
| Item.AnonRecdField (_, tys, index, _) -> tys[index]
4020-
| _ -> g.obj_ty
4020+
| _ -> g.obj_ty_ambivalent
40214021

40224022
idsBeforeField, (fieldId, item) :: (nestedFieldSearch [] fieldTy rest)
40234023

src/Compiler/Checking/QuotationTranslator.fs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1223,7 +1223,7 @@ and ConvILType cenv env m ty =
12231223
and TryElimErasableTyconRef cenv m (tcref: TyconRef) =
12241224
match tcref.TypeReprInfo with
12251225
// Get the base type
1226-
| TProvidedTypeRepr info when info.IsErased -> Some (info.BaseTypeForErased (m, cenv.g.obj_ty))
1226+
| TProvidedTypeRepr info when info.IsErased -> Some (info.BaseTypeForErased (m, cenv.g.obj_ty_withNulls))
12271227
| _ -> None
12281228
#endif
12291229

0 commit comments

Comments
 (0)