@@ -1252,8 +1252,11 @@ inductive LValResolution where
12521252 The `baseName` is the base name of the type to search for in the parameter list. -/
12531253 | localRec (baseName : Name) (fvar : Expr)
12541254
1255+ private def mkLValError (e : Expr) (eType : Expr) (msg : MessageData) : MessageData :=
1256+ m!"{msg}{indentExpr e}\n has type{indentExpr eType}"
1257+
12551258private def throwLValErrorAt (ref : Syntax) (e : Expr) (eType : Expr) (msg : MessageData) : TermElabM α :=
1256- throwErrorAt ref "{msg}{indentExpr e} \n has type{indentExpr eType}"
1259+ throwErrorAt ref (mkLValError e eType msg)
12571260
12581261private def throwLValError (e : Expr) (eType : Expr) (msg : MessageData) : TermElabM α := do
12591262 throwLValErrorAt (← getRef) e eType msg
@@ -1322,9 +1325,19 @@ where
13221325 | some (_, p2) => prodArity p2 + 1
13231326
13241327private def resolveLValAux (e : Expr) (eType : Expr) (lval : LVal) : TermElabM LValResolution := do
1325- let throwInvalidFieldAt {α : Type } (ref : Syntax) (fieldName : String) (fullName : Name) : TermElabM α := do
1326- throwLValErrorAt ref e eType <| ← mkUnknownIdentifierMessage (declHint := fullName)
1327- m!"Invalid field `{fieldName}`: The environment does not contain `{fullName}`"
1328+ let throwInvalidFieldAt {α : Type } (ref : Syntax) (fieldName : String) (fullName : Name)
1329+ (declHint := Name.anonymous) : TermElabM α := do
1330+ let msg ←
1331+ -- ordering: put decl hint, if any, last
1332+ mkUnknownIdentifierMessage (declHint := declHint)
1333+ (mkLValError e eType
1334+ m!"Invalid field `{fieldName}`: The environment does not contain `{fullName}`" )
1335+ -- HACK: Simulate previous embedding of tagged `mkUnknownIdentifierMessage`.
1336+ -- The "import unknown identifier" code action requires the tag to be present somewhere in the
1337+ -- message. But if it is at the root, the tag will also be shown to the user even though the
1338+ -- current help page does not address field notation, which should likely get its own help page
1339+ -- (if any).
1340+ throwErrorAt ref m!"{msg}{.nil}"
13281341 if eType.isForall then
13291342 match lval with
13301343 | LVal.fieldName _ fieldName suffix? fullRef =>
@@ -1390,6 +1403,9 @@ private def resolveLValAux (e : Expr) (eType : Expr) (lval : LVal) : TermElabM L
13901403 if let some (baseStructName, fullName) ← findMethod? structName (.mkSimple fieldName) then
13911404 return LValResolution.const baseStructName structName fullName
13921405 throwInvalidFieldAt fullRef fieldName fullName
1406+ -- Suggest a potential unreachable private name as hint. This does not cover structure
1407+ -- inheritance, nor `import all`.
1408+ (declHint := (mkPrivateName env structName).mkStr fieldName)
13931409 | none, LVal.fieldName _ _ (some suffix) fullRef =>
13941410 -- This may be a function constant whose implicit arguments have already been filled in:
13951411 let c := e.getAppFn
0 commit comments