-
Notifications
You must be signed in to change notification settings - Fork 455
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix issue when inlining complex constants in pattern matching.
The compiler's back-end has optimisations to inline complex constants. This can interfere with pattern matching compilation. In the tests, a person can be a Student or a Teacher. Because of inlining, the value one pattern matches on is known to be of type Teacher. However, the compilation of pattern matching still generates code for both student and teacher. The (dead) code for student is generated, but the inlined value has type teacher. This means that an attempt is made to access non-existent field "status" of teacher. Notice one could even rename "status" to "age" in Student, and the filed would exist, but just be of unexpected type. So the constant age for Teacher is interpreted as a status value (the second field of the inline record). The compiler optimisation expects to find a valid constant for status, while it finds the age. This PR catches this situation and does not try to follow a specific branch of the "status" cases but reverts to the general case.
- Loading branch information
1 parent
7e776d0
commit 124f1ad
Showing
5 changed files
with
107 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
module Test1 = { | ||
type status = Vacations(int) | Sabbatical(int) | Sick | ||
type person = | ||
| Teacher({age: int}) | ||
| Student({status: status}) | ||
|
||
let person1 = Teacher({age: 12345}) | ||
|
||
let message = switch person1 { | ||
| Student({status: Vacations(_) | Sick}) => "a" | ||
| _ => "b" | ||
} | ||
} | ||
|
||
module Test2 = { | ||
type status = Vacations(int) | Sabbatical(int) | Sick | Present | ||
type reportCard = {passing: bool, gpa: float} | ||
type person = | ||
| Teacher({name: string, age: int}) | ||
| Student({name: string, status: status, reportCard: reportCard}) | ||
|
||
let person2 = Teacher({name: "Jane", age: 12345}) | ||
|
||
let message = switch person2 { | ||
| Teacher({name: "Mary" | "Joe"}) => `Hey, still going to the party on Saturday?` | ||
| Teacher({name}) => | ||
// this is matched only if `name` isn't "Mary" or "Joe" | ||
`Hello ${name}.` | ||
| Student({name, reportCard: {passing: true, gpa}}) => | ||
`Congrats ${name}, nice GPA of ${Js.Float.toString(gpa)} you got there!` | ||
| Student({reportCard: {gpa: 0.0}, status: Vacations(daysLeft) | Sabbatical(daysLeft)}) => | ||
`Come back in ${Js.Int.toString(daysLeft)} days!` | ||
| Student({status: Sick}) => `How are you feeling?` | ||
| Student({name}) => `Good luck next semester ${name}!` | ||
} | ||
} |