-
Notifications
You must be signed in to change notification settings - Fork 825
SynType with single slash and type #13440
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
SynType with single slash and type #13440
Conversation
The idea we are going to is to split up [<Measure>]
type Foo = x * y / z // SynType.Division
type RealTuple = x * y * z // SynType.Tuple
There are some real distinctions between the two:
The helper functions The range of the let range =
(leadingType.Range, elementTypes) ||> List.fold (fun acc (_, t) -> unionRanges acc t.Range) This will combine the range of all types. Be aware that there is a bit of a twist to this PR so far:
There is no Maybe for | Division of leadingType: SynType option * elementTypes: (bool * SynType list) * range: range Where the Examples [<Measure>] type Foo = x / y
[<Measure>] type Bar = a * b / c
[<Measure>] type Bar = / second leads to Division (x, [(false, y)])
Division (a, [(true, b); (false, c)])
Division (None, [(false, second]) This is just a suggestion, but I hope you see where I'm going with this. Unit tests will need to be added to https://github.com/dotnet/fsharp/blob/0c5671f3b87e3fe076344bbf8997aa6587e582ff/tests/service/Symbols.fs to make sure we covered all the grammar rules. In the type checking, you will need to split up fsharp/src/Compiler/Checking/CheckExpressions.fs Lines 4642 to 4659 in 0c5671f
We basically already from the AST is the type is a measure or a tuple. For the The best of luck @edgarfgp. |
Oh, and in the case of It is currently present in the range of You can get this range by changing: to
val mkDivideWithLeadingSlash: leadingSlash: range -> elementTypes: (bool * SynType) list -> SynType Calculate the range in a similar fashion as in |
Thank you @nojaf for the detailed explanation :) . |
This sounds not very good to me. The type checker and various features now would need to deal with both Another approach we could consider: what if we kept the types inside |
I was unaware that a measure type with only [<Measure>] type Y
[<Measure>] type Z
[<Measure>] type X = Y * Z is allowed, so this brings us back to the drawing board @edgarfgp. We can still, however, keep the changes in We do need still need a change I think to somehow deal with Maybe changing |
@nojaf Will make the changes this evening :) . |
Yeah that sounds the only way that we can capture our edge-case without changed signature too much |
Wonder if it should be explicit about usage for units-of-measure, maybe In the current change, what is the meaning of turning Taking @nojaf suggestion example: [<Measure>] type Foo = x / y
[<Measure>] type Bar = a * b / c
[<Measure>] type Bar = / second suggestion: MeasureDivision (Some x, [(Slash, y)])
MeasureDivision (Some a, [(Star, b); (Slash, c)])
MeasureDivision (None, [(Slash, second]) Maybe being more explicit about what forms a division: Maybe it is possible to better refactor to make the fsharp/src/Compiler/SyntaxTree/SyntaxTree.fsi Lines 489 to 492 in 0c5671f
This kind of change, maybe the right time to make it more consistent, alas I am not familiar with how to better model the syntax tree, especially if this is to also contribute to error recovery around faulty measure declarations, I understand it is a can of worms 🙂. related: #11481 PS: Kudos to @nojaf for pairing with @edgarfgp and congrats to @edgarfgp for tackling parser related issues! |
@smoothdeveloper as Eugene mentioned, the [<Measure>] type X = Y * Z
type MyTuple = int * string In both cases, the right-hand side is So changing the semantics from |
Got it, overlooked that, thanks @nojaf! Then, The pretty printing also shows interesting stuff: [<Measure>] type x
[<Measure>] type y
[<Measure>] type z
[<Measure>] type A = x * y / z
[<Measure>] type B = x * z / y * z
[<Measure>] type C = x y / z outputing: [<Measure>]
type A = x y/z
[<Measure>]
type B = x z ^ 2/y
[<Measure>]
type C = x y/z it seems one can omit the Really interesting area. |
@@ -819,7 +819,7 @@ module SyntaxTraversal = | |||
| SynType.Array (_, ty, _) -> traverseSynType path ty | |||
| SynType.StaticConstantNamed (ty1, ty2, _) | |||
| SynType.MeasureDivide (ty1, ty2, _) -> [ ty1; ty2 ] |> List.tryPick (traverseSynType path) | |||
| SynType.Tuple (_, tys, _) -> tys |> List.map snd |> List.tryPick (traverseSynType path) | |||
| SynType.Tuple(_, _, _, elements, _) -> elements |> List.map snd |> List.tryPick (traverseSynType path) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@edgarfgp is it important that we still include the firstType
into the existing code.
I think here we need something like firstType :: (List.map snd elements) |> List.tryPick (traverseSynType path) Write Preview
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had some time today and I made a change based on your suggestion :)
Introduce TupleTypeSegment to SynType.Tuple.
Update SurfaceArea
There seems to be a unit test failing but they all pass locally using sh build.sh --test -c Release. Will try rerunning the CI |
Non measure kinds are not measures.
@dsyme Can we have a review please ? |
@@ -811,3 +811,15 @@ let mkSynMemberDefnGetSet | |||
[] | |||
| _ -> [] | |||
| _ -> [] | |||
|
|||
// The last element of elementTypes does not have a star or slash | |||
let mkTupleOrDivide (isStruct: bool) (elementTypes: TupleTypeSegment list) : SynType = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would rename this to mkSynTypeTuple
, we already moved away from the divide
thing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated. Thanks for the comment :)
@@ -427,6 +427,14 @@ type SynTyparDecls = | |||
member Constraints: SynTypeConstraint list | |||
member Range: range | |||
|
|||
[<NoEquality; NoComparison; RequireQualifiedAccess>] | |||
type TupleTypeSegment = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please call this SynTupleTypeSegment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done, thanks for the review @dsyme!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just one small request for change
Rename TupleTypeSegment to SynTupleTypeSegment.
Pair programming session with @nojaf
First attempt to fix #13348