Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Show obsolete warnings/errors when used with unit of measure #18182

Merged
merged 31 commits into from
Jan 9, 2025
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
5c21e2f
Show obsolete warnings/errors when used with unit of measure
edgarfgp Dec 29, 2024
15cbc6c
format code
edgarfgp Dec 29, 2024
633cdfc
refactor
edgarfgp Dec 29, 2024
2ffae64
release notes
edgarfgp Dec 29, 2024
640f370
Merge branch 'main' into fix-18181
edgarfgp Dec 31, 2024
909842b
Merge branch 'main' into fix-18181
edgarfgp Jan 2, 2025
a3cca3a
Move logic to Checking phase
edgarfgp Jan 2, 2025
a1f68f4
Revert changes from PIC
edgarfgp Jan 3, 2025
d15381d
Test for unit-of-measures in class bindings and members
edgarfgp Jan 3, 2025
790bf50
Remove unneeded range from SynMeasure.Power
edgarfgp Jan 3, 2025
61fed85
Update CheckDeclarations
edgarfgp Jan 3, 2025
ae8c930
Merge branch 'main' into fix-18181
edgarfgp Jan 3, 2025
7a5fcdb
Use better ranges
edgarfgp Jan 3, 2025
517b474
Merge branch 'fix-18181' of github.com:edgarfgp/fsharp into fix-18181
edgarfgp Jan 3, 2025
1774bec
More tests
edgarfgp Jan 3, 2025
7c71c9c
Update SurfaceArea
edgarfgp Jan 3, 2025
106550d
Reduce diff in ConstraintSolver.fs
edgarfgp Jan 4, 2025
1e3a8cd
Reduce diff
edgarfgp Jan 4, 2025
87d772e
Remove unnecessary bool flag
edgarfgp Jan 4, 2025
d4a0dda
Reduce diff
edgarfgp Jan 4, 2025
f2c398b
Add CheckUnitOfMeasureAttributes in AttributeChecking
edgarfgp Jan 6, 2025
0a2f9ca
Merge branch 'main' into fix-18181
edgarfgp Jan 6, 2025
313a4c3
Merge branch 'main' into fix-18181
edgarfgp Jan 6, 2025
61d289c
Merge branch 'main' into fix-18181
edgarfgp Jan 7, 2025
fe80cac
Merge branch 'main' into fix-18181
edgarfgp Jan 7, 2025
843f5f6
handle expression has more than 1 type parameter
edgarfgp Jan 7, 2025
f502c9f
Merge branch 'main' into fix-18181
edgarfgp Jan 7, 2025
59886f4
one more check
edgarfgp Jan 8, 2025
39cef7a
Merge branch 'fix-18181' of github.com:edgarfgp/fsharp into fix-18181
edgarfgp Jan 8, 2025
b755cd0
Move the check to TcConstExpr
edgarfgp Jan 8, 2025
2fe067e
Merge branch 'main' into fix-18181
edgarfgp Jan 9, 2025
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
1 change: 1 addition & 0 deletions docs/release-notes/.FSharp.Compiler.Service/9.0.200.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
* Completion: fix qualified completion in sequence expressions [PR #18111](https://github.com/dotnet/fsharp/pull/18111)
* Symbols: try to use ValReprInfoForDisplay in Mfv.CurriedParameterGroups ([PR #18124](https://github.com/dotnet/fsharp/pull/18124))
* Shim/file system: fix leaks of the shim [PR #18144](https://github.com/dotnet/fsharp/pull/18144)
* Fix for `Obsolete` attribute warning/error not taken into account when used with a unit of measure [PR #18182](https://github.com/dotnet/fsharp/pull/18182)

### Added

Expand Down
6 changes: 3 additions & 3 deletions src/Compiler/Checking/CheckDeclarations.fs
Original file line number Diff line number Diff line change
Expand Up @@ -3807,11 +3807,11 @@ module EstablishTypeDefinitionCores =

and accInMeasure measureTy acc =
match stripUnitEqns measureTy with
| Measure.Const tcref when ListSet.contains (===) tcref.Deref tycons ->
| Measure.Const(tyconRef= tcref) when ListSet.contains (===) tcref.Deref tycons ->
(tycon, tcref.Deref) :: acc
| Measure.Const tcref when tcref.IsTypeAbbrev ->
| Measure.Const(tyconRef= tcref) when tcref.IsTypeAbbrev ->
accInMeasure (reduceTyconRefAbbrevMeasureable tcref) acc
| Measure.Prod (ms1, ms2) -> accInMeasure ms1 (accInMeasure ms2 acc)
| Measure.Prod(measure1= ms1; measure2= ms2) -> accInMeasure ms1 (accInMeasure ms2 acc)
| Measure.Inv invTy -> accInMeasure invTy acc
| _ -> acc

Expand Down
47 changes: 24 additions & 23 deletions src/Compiler/Checking/ConstraintSolver.fs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@

module internal FSharp.Compiler.ConstraintSolver

open FSharp.Compiler.Text.Range
open Internal.Utilities.Collections
open Internal.Utilities.Library
open Internal.Utilities.Library.Extras
Expand Down Expand Up @@ -729,12 +730,12 @@ let SubstMeasureWarnIfRigid (csenv: ConstraintSolverEnv) trace (v: Typar) ms =
let tpnmOpt = if v.IsCompilerGenerated then None else Some v.Name
do! SolveTypStaticReq csenv trace v.StaticReq (TType_measure ms)
SubstMeasure v ms
return! WarnD(NonRigidTypar(csenv.DisplayEnv, tpnmOpt, v.Range, TType_measure (Measure.Var v), TType_measure ms, csenv.m))
return! WarnD(NonRigidTypar(csenv.DisplayEnv, tpnmOpt, v.Range, TType_measure (Measure.Var(v, v.Range)), TType_measure ms, csenv.m))
else
// Propagate static requirements from 'tp' to 'ty'
do! SolveTypStaticReq csenv trace v.StaticReq (TType_measure ms)
SubstMeasure v ms
if v.Rigidity = TyparRigidity.Anon && measureEquiv csenv.g ms Measure.One then
if v.Rigidity = TyparRigidity.Anon && measureEquiv csenv.g ms (Measure.One(ms.Range)) then
return! WarnD(Error(FSComp.SR.csCodeLessGeneric(), v.Range))
else
()
Expand All @@ -760,17 +761,17 @@ let UnifyMeasureWithOne (csenv: ConstraintSolverEnv) trace ms =
match FindPreferredTypar nonRigidVars with
| (v, e) :: vs ->
let unexpandedCons = ListMeasureConOccsWithNonZeroExponents csenv.g false ms
let newms = ProdMeasures (List.map (fun (c, e') -> Measure.RationalPower (Measure.Const c, NegRational (DivRational e' e))) unexpandedCons
@ List.map (fun (v, e') -> Measure.RationalPower (Measure.Var v, NegRational (DivRational e' e))) (vs @ rigidVars))
let newms = ProdMeasures (List.map (fun (c, e') -> Measure.RationalPower(Measure.Const(c, c.Range), NegRational (DivRational e' e), ms.Range)) unexpandedCons
@ List.map (fun (v, e') -> Measure.RationalPower (Measure.Var(v, v.Range), NegRational (DivRational e' e), ms.Range)) (vs @ rigidVars))

SubstMeasureWarnIfRigid csenv trace v newms

// Otherwise we require ms to be 1
| [] -> if measureEquiv csenv.g ms Measure.One then CompleteD else localAbortD
| [] -> if measureEquiv csenv.g ms (Measure.One(ms.Range)) then CompleteD else localAbortD

/// Imperatively unify unit-of-measure expression ms1 against ms2
let UnifyMeasures (csenv: ConstraintSolverEnv) trace ms1 ms2 =
UnifyMeasureWithOne csenv trace (Measure.Prod(ms1, Measure.Inv ms2))
UnifyMeasureWithOne csenv trace (Measure.Prod(ms1, Measure.Inv ms2, (unionRanges ms1.Range ms2.Range)))

/// Simplify a unit-of-measure expression ms that forms part of a type scheme.
/// We make substitutions for vars, which are the (remaining) bound variables
Expand All @@ -785,18 +786,18 @@ let SimplifyMeasure g vars ms =
let newvar = if v.IsCompilerGenerated then NewAnonTypar (TyparKind.Measure, v.Range, TyparRigidity.Flexible, v.StaticReq, v.DynamicReq)
else NewNamedInferenceMeasureVar (v.Range, TyparRigidity.Flexible, v.StaticReq, v.Id)
let remainingvars = ListSet.remove typarEq v vars
let newvarExpr = if SignRational e < 0 then Measure.Inv (Measure.Var newvar) else Measure.Var newvar
let newvarExpr = if SignRational e < 0 then Measure.Inv (Measure.Var(newvar, newvar.Range)) else Measure.Var(newvar, newvar.Range)
let nonZeroCon = ListMeasureConOccsWithNonZeroExponents g false ms
let nonZeroVar = ListMeasureVarOccsWithNonZeroExponents ms
let newms =
ProdMeasures [
for (c, e') in nonZeroCon do
Measure.RationalPower (Measure.Const c, NegRational (DivRational e' e))
Measure.RationalPower (Measure.Const(c, c.Range), NegRational (DivRational e' e), ms.Range)
for (v', e') in nonZeroVar do
if typarEq v v' then
newvarExpr
else
Measure.RationalPower (Measure.Var v', NegRational (DivRational e' e))
Measure.RationalPower (Measure.Var(v', v'.Range), NegRational (DivRational e' e), ms.Range)
]
SubstMeasure v newms
match vs with
Expand Down Expand Up @@ -880,7 +881,7 @@ let NormalizeExponentsInTypeScheme uvars ty =
v
else
let v' = NewAnonTypar (TyparKind.Measure, v.Range, TyparRigidity.Flexible, v.StaticReq, v.DynamicReq)
SubstMeasure v (Measure.RationalPower (Measure.Var v', DivRational OneRational expGcd))
SubstMeasure v (Measure.RationalPower (Measure.Var(v', v'.Range), DivRational OneRational expGcd, v.Range))
v')

// We normalize unit-of-measure-polymorphic type schemes. There
Expand Down Expand Up @@ -922,7 +923,7 @@ let SimplifyMeasuresInTypeScheme g resultFirst (generalizable: Typar list) ty co
let generalized' = NormalizeExponentsInTypeScheme generalized ty
vars @ List.rev generalized'

let freshMeasure () = Measure.Var (NewInferenceMeasurePar ())
let freshMeasure () = Measure.Var((NewInferenceMeasurePar ()), range0)

let CheckWarnIfRigid (csenv: ConstraintSolverEnv) ty1 (r: Typar) ty =
let g = csenv.g
Expand Down Expand Up @@ -1112,7 +1113,7 @@ and SolveTyparEqualsType (csenv: ConstraintSolverEnv) ndeep m2 (trace: OptionalT
do! DepthCheck ndeep m
match ty1 with
| TType_var (r, _)
| TType_measure (Measure.Var r) ->
| TType_measure (Measure.Var(r, _)) ->
do! SolveTyparEqualsTypePart1 csenv m2 trace ty1 r ty
do! SolveTyparEqualsTypePart2 csenv ndeep m2 trace r ty
| _ -> failwith "SolveTyparEqualsType"
Expand All @@ -1125,15 +1126,15 @@ and SolveTyparsEqualTypes (csenv: ConstraintSolverEnv) ndeep m2 (trace: Optional
fun tpTy ty ->
match tpTy with
| TType_var (r, _)
| TType_measure (Measure.Var r) ->
| TType_measure (Measure.Var(r, _)) ->
SolveTyparEqualsTypePart1 csenv m2 trace tpTy r ty
| _ ->
failwith "SolveTyparsEqualTypes") tpTys tys
do! Iterate2D (
fun tpTy ty ->
match tpTy with
| TType_var (r, _)
| TType_measure (Measure.Var r) ->
| TType_measure (Measure.Var(r, _)) ->
SolveTyparEqualsTypePart2 csenv ndeep m2 trace r ty
| _ ->
failwith "SolveTyparsEqualTypes") tpTys tys
Expand Down Expand Up @@ -1329,13 +1330,13 @@ and SolveTypeEqualsType (csenv: ConstraintSolverEnv) ndeep m2 (trace: OptionalTr
// Catch float<_>=float<1>, float32<_>=float32<1> and decimal<_>=decimal<1>
| (_, TType_app (tc2, [ms2], _)) when (tc2.IsMeasureableReprTycon && typeEquiv csenv.g sty1 (reduceTyconRefMeasureableOrProvided csenv.g tc2 [ms2])) ->
trackErrors {
do! SolveTypeEqualsType csenv ndeep m2 trace None (TType_measure Measure.One) ms2
do! SolveTypeEqualsType csenv ndeep m2 trace None (TType_measure(Measure.One(m2))) ms2
do! SolveNullnessEquiv csenv m2 trace ty1 ty2 (nullnessOfTy g sty1) (nullnessOfTy g sty2)
}

| (TType_app (tc1, [ms1], _), _) when (tc1.IsMeasureableReprTycon && typeEquiv csenv.g sty2 (reduceTyconRefMeasureableOrProvided csenv.g tc1 [ms1])) ->
trackErrors {
do! SolveTypeEqualsType csenv ndeep m2 trace None ms1 (TType_measure Measure.One)
do! SolveTypeEqualsType csenv ndeep m2 trace None ms1 (TType_measure(Measure.One(m2)))
do! SolveNullnessEquiv csenv m2 trace ty1 ty2 (nullnessOfTy g sty1) (nullnessOfTy g sty2)
}

Expand Down Expand Up @@ -1518,13 +1519,13 @@ and SolveTypeSubsumesType (csenv: ConstraintSolverEnv) ndeep m2 (trace: Optional
// Enforce the identities float=float<1>, float32=float32<1> and decimal=decimal<1>
| _, TType_app (tc2, [ms2], _) when tc2.IsMeasureableReprTycon && typeEquiv csenv.g sty1 (reduceTyconRefMeasureableOrProvided csenv.g tc2 [ms2]) ->
trackErrors {
do! SolveTypeEqualsTypeKeepAbbrevsWithCxsln csenv ndeep m2 trace cxsln ms2 (TType_measure Measure.One)
do! SolveTypeEqualsTypeKeepAbbrevsWithCxsln csenv ndeep m2 trace cxsln ms2 (TType_measure(Measure.One(m2)))
do! SolveNullnessSubsumesNullness csenv m2 trace ty1 ty2 (nullnessOfTy g sty1) (nullnessOfTy g sty2)
}

| TType_app (tc1, [ms1], _), _ when tc1.IsMeasureableReprTycon && typeEquiv csenv.g sty2 (reduceTyconRefMeasureableOrProvided csenv.g tc1 [ms1]) ->
trackErrors {
do! SolveTypeEqualsTypeKeepAbbrevsWithCxsln csenv ndeep m2 trace cxsln ms1 (TType_measure Measure.One)
do! SolveTypeEqualsTypeKeepAbbrevsWithCxsln csenv ndeep m2 trace cxsln ms1 (TType_measure(Measure.One(m2)))
do! SolveNullnessSubsumesNullness csenv m2 trace ty1 ty2 (nullnessOfTy g sty1) (nullnessOfTy g sty2)
}

Expand Down Expand Up @@ -1620,7 +1621,7 @@ and DepthCheck ndeep m =
and SolveDimensionlessNumericType (csenv: ConstraintSolverEnv) ndeep m2 trace ty =
match getMeasureOfType csenv.g ty with
| Some (tcref, _) ->
SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace ty (mkWoNullAppTy tcref [TType_measure Measure.One])
SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace ty (mkWoNullAppTy tcref [TType_measure(Measure.One(m2))])
| None ->
CompleteD

Expand Down Expand Up @@ -1727,7 +1728,7 @@ and SolveMemberConstraint (csenv: ConstraintSolverEnv) ignoreUnresolvedOverload
| Some (tcref, ms1) ->
let ms2 = freshMeasure ()
do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argTy2 (mkWoNullAppTy tcref [TType_measure ms2])
do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy (mkWoNullAppTy tcref [TType_measure (Measure.Prod(ms1, if nm = "op_Multiply" then ms2 else Measure.Inv ms2))])
do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy (mkWoNullAppTy tcref [TType_measure (Measure.Prod(ms1, (if nm = "op_Multiply" then ms2 else Measure.Inv ms2), unionRanges ms1.Range ms2.Range))])
return TTraitBuiltIn

| _ ->
Expand All @@ -1736,7 +1737,7 @@ and SolveMemberConstraint (csenv: ConstraintSolverEnv) ignoreUnresolvedOverload
| Some (tcref, ms2) ->
let ms1 = freshMeasure ()
do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argTy1 (mkWoNullAppTy tcref [TType_measure ms1])
do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy (mkWoNullAppTy tcref [TType_measure (Measure.Prod(ms1, if nm = "op_Multiply" then ms2 else Measure.Inv ms2))])
do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy (mkWoNullAppTy tcref [TType_measure (Measure.Prod(ms1, (if nm = "op_Multiply" then ms2 else Measure.Inv ms2), unionRanges ms1.Range ms2.Range))])
return TTraitBuiltIn

| _ ->
Expand Down Expand Up @@ -1870,7 +1871,7 @@ and SolveMemberConstraint (csenv: ConstraintSolverEnv) ignoreUnresolvedOverload
match getMeasureOfType g argTy1 with
| Some (tcref, _) ->
let ms1 = freshMeasure ()
do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argTy1 (mkWoNullAppTy tcref [TType_measure (Measure.Prod (ms1, ms1))])
do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argTy1 (mkWoNullAppTy tcref [TType_measure (Measure.Prod (ms1, ms1, ms1.Range))])
do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy (mkWoNullAppTy tcref [TType_measure ms1])
return TTraitBuiltIn
| None ->
Expand Down Expand Up @@ -1923,7 +1924,7 @@ and SolveMemberConstraint (csenv: ConstraintSolverEnv) ignoreUnresolvedOverload
do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argTy2 argTy1
match getMeasureOfType g argTy1 with
| None -> do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy argTy1
| Some (tcref, _) -> do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy (mkWoNullAppTy tcref [TType_measure Measure.One])
| Some (tcref, _) -> do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy (mkWoNullAppTy tcref [TType_measure(Measure.One(tcref.Range))])
return TTraitBuiltIn

| _ ->
Expand Down
Loading
Loading