Home
About
Blog
Products
Forum
Support
Contact
Sunbelt Computer Software
PL/B Language Development and Support
Home
About
Blog
Products
Forum
Support
Contact
unison/unison-src/example-errors.u at websiteExecutable · JavaDerek/unison · GitHub
Skip to content
Navigation Menu
Sign in
Appearance settings
Platform
AI CODE CREATION
GitHub Copilot
Write better code with AI
GitHub Copilot app
Direct agents from issue to merge
MCP Registry
Integrate external tools
DEVELOPER WORKFLOWS
Actions
Automate any workflow
Codespaces
Instant dev environments
Issues
Plan and track work
Code Review
Manage code changes
Code Quality
Enforce quality at merge
APPLICATION SECURITY
GitHub Advanced Security
Find and fix vulnerabilities
Code security
Secure your code as you build
Secret protection
Stop leaks before they start
EXPLORE
Why GitHub
Documentation
Blog
Changelog
Marketplace
View all features
Solutions
BY COMPANY SIZE
Enterprises
Small and medium teams
Startups
Nonprofits
BY USE CASE
App Modernization
DevSecOps
DevOps
CI/CD
View all use cases
BY INDUSTRY
Healthcare
Financial services
Manufacturing
Government
View all industries
View all solutions
Resources
EXPLORE BY TOPIC
AI
Software Development
DevOps
Security
View all topics
EXPLORE BY TYPE
Customer stories
Events & webinars
Ebooks & reports
Business insights
GitHub Skills
SUPPORT & SERVICES
Documentation
Customer support
Community forum
Trust center
Partners
View all resources
Open Source
COMMUNITY
GitHub Sponsors
Fund open source developers
PROGRAMS
Security Lab
Maintainer Community
GitHub Stars
Archive Program
REPOSITORIES
Topics
Trending
Collections
Enterprise
ENTERPRISE SOLUTIONS
Enterprise platform
AI-powered developer platform
AVAILABLE ADD-ONS
GitHub Advanced Security
Enterprise-grade security features
Copilot for Business
Enterprise-grade AI features
Premium Support
Enterprise-grade 24/7 support
Pricing
Search
/
Sign in
Sign up
Appearance settings
You signed in with another tab or window.
Reload
to refresh your session.
You signed out in another tab or window.
Reload
to refresh your session.
You switched accounts on another tab or window.
Reload
to refresh your session.
Dismiss alert
{{ message }}
JavaDerek
unison
Repository navigation
Code
Pull requests
Actions
Projects
Security and quality
Insights
More
items
Files
Expand file tree
websiteExecutable
Breadcrumbs
unison
/
unison-src
/
example-errors.u
Copy path
Blame
More file actions
Blame
More file actions
Latest commit
History
History
History
181 lines (145 loc) · 5.71 KB
websiteExecutable
Breadcrumbs
unison
/
unison-src
/
example-errors.u
Copy path
Top
File metadata and controls
Code
Blame
181 lines (145 loc) · 5.71 KB
Raw
Copy raw file
Download raw file
Open symbols panel
Edit and raw actions
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
-- Each of the programs in this file generates an error of some sort.
-- We want error messages to be awesome so for each wrong program we
-- give "the ideal error message" and a uniform, simple algorithm for producing
-- that message.
ex1 : Int
ex1 = "hello"
{- Ideal error:
Type mismatch in example-errors.u, line 6: `Text` vs `Int`
|
6 | ex1 = "hello"
| ^^^^^^^
`Text` comes from a literal:
|
6 | ex1 = "hello"
| ^^^^^^^
`Int` comes from type signature:
|
5 | ex1 : Int
| ^^^^^
Thoughts:
* The first line marker is the _site of the error_
* The next two line markers are the _provenance of the mismatched types_
* In this case, the provenance of `Text` is the same location as the error,
but this won't always be the case. Optimized message just omits the
site of the error if it matches the provenance location of either of
the mismatched types.
* The backticks might be in color, formatted as bold, whatever, be
thoughtful about using visual indicators to draw attention to most important
aspects of the message.
* For implementation - when `check e t` hits `Term.Text'`, it does:
`subtype Type.text t`, but `Type.text` requires a `loc`, and we'll provide
`ABT.annotation e`. This logic can go in synthesize.
* Q: should we just ALWAYS set the location of a synthesized type
to be the location of the term that type was synthesized from?
* A: No,
foo : Text
foo x =
y = x + 1
x
In this example, x will synthesize to the type `Int`, but the location
of that type shouldn't just be
* When you synthesize a type for a lambda, `x -> x`
the location of the synthesized type `∀ a . a -> a`
is just the location of `x -> x`.
The location of the `a` also needs to be this same location.
Might want to have a special kind of location which indicates
that the location came from an inferred type.
-}
ex2 : Int -- `Int` comes from
ex2 =
y = "hello" -- `Text` comes from "hello"
y
{- Ideal error:
example-errors.u contained errors:
The highlighted expression on line 42
|
42 | y
| ^
was inferred to have type `Text` but was expected to have type `Int`
`Int` comes from type signature:
|
39 | ex2 : Int
| ^^^^^
`Text` was inferred from a literal:
|
41 | y = "hello"
| ^^^^^^^
Thoughts:
* `y` is the body of the block, and the body of the block is expected to
have type `Int`
* Maybe use bold or some visual indicator rather than the ^^^ nonsense
* Do we include parent scopes?
-}
ex3 =
x = 1 + 1
if x then 42 else "hkjh"
{-
example-errors.u contained 1 error:
-- 1 -------------------------------------------------------
The highlighted expression on line 73
|
73 | if x then 42 else -1
| ^
has type `Nat` but was expected to have type `Boolean`
`Boolean` comes from `if`, whose first argument must be of type `Boolean`
`Nat` comes from line 72:
|
72 | x = 1 + 1
| ^
x = id 42
^^^^^
^^
* "The function <...> expects its <n>th argument to be of type <...>, but
on line <m> it appears to have type <...>."
* `synthesizeApp` can take an argument for what numberth argument it's
testing
* "An if-expression expects its condition to be of type Boolean, but
* In a `synthesizeApp`, report the function input type first, as the
"expected" type.
* `if` and other builtin syntax should have some special treatment.
* Might want signature of function whose application was involved in the
mismatched types. (But don't necessarily want to dump this on users up
front, like GHC tells you the type of every binding in the vicinity)
* Issue maybe not that you didn't know the function's type, but that
you were wrong about the types of the args you passed; also, you might
accidentally omit an argument, supply an extra argument, or supply
arguments in the wrong order.
* We don't bother reporting the other type errors in the same expression,
but we potentially could have an algorithm that could do more fine-grained
recovery.
* Not totally sure on the location of the `Nat`, but the thought
is that if `+` is monomorophic in its return type (always `Nat`),
then it makes sense to attribute the `Nat` of `x` to the `+` call site.
(why not attibute that to the definition site of `+`?)
* Is this inconsistent with treatment of `Boolean` location??
* Since `if` is monomorphic in its first arg, we could use the same logic to
say that the location of that Boolean argument type is the call site
rather than its definition site.
* When encounter an error for a variable x, can add that to an erroneous
variables set - if you ever encounter a subexpression that references
those variables, skip over it?
-}
ex4 f x =
if f x then f 42 else 50
{-
Type mismatch on line <line>: `Nat` vs `Boolean`.
`Nat` comes from the literal:
|
42 | if f x then f 42 else 50
| ^^
∀ a -> [(a, Tree (Text a)) -> (a -> Text -> Text) -> Tree Text
∀ a . Boolean -> a -> a
Not sure what to report for the origin of the `Boolean`:
`Boolean` comes from `f 42`??
`Boolean` comes from `f : Nat -> Boolean`??
But then why does `f` have that type?
Because `if` takes a `Boolean` as first arg..
`Boolean` comes from `if`
`f 42` has type `Boolean` because `f` had to have type `x -> Boolean`
because `f x` was passed as the first argument of `if`:
if f x then f 42 else 50
^^^
Arya thought - when there's a type mismatch between A and B, and A and B
are both inferred types, might make sense to provide more info about provenance.
-}
You can’t perform that action at this time.