Skip to content

Commit e3f0acb

Browse files
committed
Specify error explanation more specifically
1 parent 92f02ac commit e3f0acb

File tree

2 files changed

+42
-21
lines changed

2 files changed

+42
-21
lines changed

src/Lean/Elab/App.lean

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1375,25 +1375,27 @@ private def resolveLValAux (e : Expr) (eType : Expr) (lval : LVal) : TermElabM L
13751375
throwError "Invalid projection: Projections cannot be used on functions, and{indentExpr e}\n\
13761376
has function type{inlineExprTrailing eType}"
13771377

1378-
| .mvar .., lval =>
1379-
let (notationKind, _, projKind, projName) := getLValDesc lval
1380-
throwError m!"Invalid {notationKind}: Type of{indentExpr e}\nis not known; cannot resolve {projKind} `{projName}`"
1378+
| .mvar .., .fieldName _ fieldName _ _ =>
1379+
throwNamedError lean.invalidField m!"Invalid field notation: Type of{indentExpr e}\nis not \
1380+
known; cannot resolve field `{fieldName}`"
1381+
| .mvar .., .fieldIdx _ i =>
1382+
throwError m!"Invalid projection: Type of{indentExpr e}\nis not known; cannot resolve \
1383+
projection `{i}`"
13811384

13821385
| _, _ =>
13831386
match e.getAppFn, lval with
13841387
| Expr.const c _, .fieldName _ref _fieldName (some suffix) _fullRef =>
13851388
throwUnknownConstant (c ++ suffix)
1386-
| _, _ =>
1387-
let (notationKind, notationDesc, _, _) := getLValDesc lval
1388-
throwNamedError lean.invalidField m!"Invalid {notationKind}: {notationDesc} operates on \
1389-
types of the form `C ...` where C is a constant. The expression{indentExpr e}\nhas \
1390-
type{inlineExpr eType}which does not have the necessary form."
1389+
| _, .fieldName .. =>
1390+
throwNamedError lean.invalidField m!"Invalid field notation: Field projection operates on \
1391+
types of the form `C ...` where C is a constant. The expression{indentExpr e}\nhas \
1392+
type{inlineExpr eType}which does not have the necessary form."
1393+
| _, .fieldIdx _ i =>
1394+
throwError m!"Invalid projection: Projection operates on types of the form `C ...` where C \
1395+
is a constant. The expression{indentExpr e}\nhas type{inlineExpr eType}which does not have \
1396+
the necessary form."
13911397

13921398
where
1393-
getLValDesc : LVal → String × String × String × String
1394-
| .fieldName _ fieldName _ _ => ("field notation", "Field projection", "field", s!"{fieldName}")
1395-
| .fieldIdx _ i => ("projection", "Projection", "projection", s!"{i}")
1396-
13971399
throwInvalidFieldAt {α : Type} (ref : Syntax) (fieldName : String) (fullName : Name)
13981400
(declHint := Name.anonymous) : TermElabM α := do
13991401
let msg ←
@@ -1403,9 +1405,8 @@ where
14031405
possible to project the field `{fieldName}` from an expression{indentExpr e}\nof \
14041406
type{inlineExprTrailing eType}"
14051407
-- By using `mkUnknownIdentifierMessage`, the tag `Lean.unknownIdentifierMessageTag` is
1406-
-- incorporated tag included within the message, as required for the "import unknown identifier"
1407-
-- code action. The "outermost" lean.invalidField name is the only one that triggers an error
1408-
-- explanation.
1408+
-- incorporated within the message, as required for the "import unknown identifier" code action.
1409+
-- The "outermost" lean.invalidField name is the only one that triggers an error explanation.
14091410
throwNamedErrorAt ref lean.invalidField msg
14101411

14111412

src/Lean/ErrorExplanations/InvalidField.lean

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,9 @@ and be a calling a function on the value `color` with
2727
#eval (4 + 2).suc
2828
```
2929
```output
30-
Invalid field `suc`: The environment does not contain `Nat.suc`, so it is not possible to project the field `suc` from an expression `4 + 2` of type `Nat`
30+
Invalid field `suc`: The environment does not contain `Nat.suc`, so it is not possible to project the field `suc` from an expression
31+
4 + 2
32+
of type `Nat`
3133
```
3234
```lean fixed
3335
#eval (4 + 1).succ
@@ -41,7 +43,9 @@ The simplest reason fo
4143
#eval '>'.leftpad 10 ['a', 'b', 'c']
4244
```
4345
```output
44-
Invalid field `leftpad`: The environment does not contain `Char.leftpad`, so it is not possible to project the field `leftpad` from an expression `'>'` of type `Char`
46+
Invalid field `leftpad`: The environment does not contain `Char.leftpad`, so it is not possible to project the field `leftpad` from an expression
47+
'>'
48+
of type `Char`
4549
```
4650
```lean fixed
4751
#eval ['a', 'b', 'c'].leftpad 10 '>'
@@ -51,17 +55,16 @@ The type of the expression before the dot determines the function being called b
5155
the dot. There is no `Char.leftpad`, and the only way to invoke `List.leftpad` with generalized
5256
field notation is to have the list come before the dot.
5357
54-
## Insufficient Type Information
58+
## Type is Not Specific
5559
5660
```lean broken
5761
def double_plus_one {α} [Add α] (x : α) :=
5862
(x + x).succ
5963
```
6064
```output
61-
Invalid field notation: Type is not of the form `C ...` where C is a constant
65+
Invalid field notation: Field projection operates on types of the form `C ...` where C is a constant. The expression
6266
x + x
63-
has type
64-
α
67+
has type `α` which does not have the necessary form.
6568
```
6669
```lean fixed
6770
def double_plus_one (x : Nat) :=
@@ -71,6 +74,23 @@ def double_plus_one (x : Nat) :=
7174
The `Add` typeclass is sufficient to for the addition `x + x`, but the `.succ` field notation
7275
cannot operate without knowing more about the actual type from which `succ` is being projected.
7376
77+
## Insufficient Type Information
78+
79+
```lean broken
80+
example := fun (n) => n.succ.succ
81+
```
82+
```output
83+
Invalid field notation: Type of
84+
n
85+
is not known; cannot resolve field `succ`
86+
```
87+
```lean fixed
88+
example := fun (n : Nat) => n.succ.succ
89+
```
90+
91+
Generalized field notation can only be used when it is possible to determine the type that is being
92+
projected. Type annotations may therefore need to be added to make generalized field notation work.
93+
7494
-/
7595
register_error_explanation lean.invalidField {
7696
summary := "Dotted identifier notation used without ."

0 commit comments

Comments
 (0)