-
Notifications
You must be signed in to change notification settings - Fork 326
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
Type ascriptions not accepted in tail position #7841
Comments
Currently the parser allows type signatures anywhere in a block. We could treat the last line of a block specially, since a type ascription is clearly more likely to be the intent in that case. In the meantime another option for a workaround would be |
Actually, I checked
still yields
|
Huh. That is actually a separate bug, in
|
Investigating. Following diff seems to enable the proper behavior: diff --git engine/runtime-compiler/src/main/scala/org/enso/compiler/pass/analyse/FramePointerAnalysis.scala engine/runtime-compiler/src/main/scala/org/enso/compiler/pass/analyse/FramePointerAnalysis.scala
index a524f70ebf..3270abef23 100644
--- engine/runtime-compiler/src/main/scala/org/enso/compiler/pass/analyse/FramePointerAnalysis.scala
+++ engine/runtime-compiler/src/main/scala/org/enso/compiler/pass/analyse/FramePointerAnalysis.scala
@@ -12,7 +12,8 @@ import org.enso.compiler.core.ir.{
Function,
Module,
Name,
- Pattern
+ Pattern,
+ Type
}
import org.enso.compiler.core.ir.module.scope.Definition
import org.enso.compiler.core.ir.module.scope.definition.Method
@@ -163,6 +164,9 @@ case object FramePointerAnalysis extends IRPass {
caseExpr.branches.foreach { branch =>
processCaseBranch(branch)
}
+ case asc: Type.Ascription =>
+ processExpression(asc.typed, graph)
+ processExpression(asc.signature, graph)
case _ => ()
}
if (updateSymbols) {
diff --git engine/runtime-compiler/src/main/scala/org/enso/compiler/pass/resolve/TypeSignatures.scala engine/runtime-compiler/src/main/scala/org/enso/compiler/pass/resolve/TypeSignatures.scala
index 10f52ce9d5..fc01693c85 100644
--- engine/runtime-compiler/src/main/scala/org/enso/compiler/pass/resolve/TypeSignatures.scala
+++ engine/runtime-compiler/src/main/scala/org/enso/compiler/pass/resolve/TypeSignatures.scala
@@ -315,7 +315,13 @@ case object TypeSignatures extends IRPass {
lastSignature = None
res
case a => Some(resolveExpression(a))
- } ::: lastSignature.map(errors.Unexpected.TypeSignature(_)).toList
+ } ::: lastSignature.map({
+ case asc @ Type.Ascription(_:Name, sig, comment, _, _) =>
+ asc.updateMetadata(
+ new MetadataPair(this, Signature(sig, comment))
+ )
+ case any => errors.Unexpected.TypeSignature(any)
+ }).toList
block.copy(
expressions = newExpressions.init,
diff --git engine/runtime/src/main/scala/org/enso/interpreter/runtime/IrToTruffle.scala engine/runtime/src/main/scala/org/enso/interpreter/runtime/IrToTruffle.scala
index c7b47140b4..5c7a306bb6 100644
--- engine/runtime/src/main/scala/org/enso/interpreter/runtime/IrToTruffle.scala
+++ engine/runtime/src/main/scala/org/enso/interpreter/runtime/IrToTruffle.scala
@@ -878,7 +878,8 @@ class IrToTruffle(
// Type contexts aren't currently really used. But we should still check the base type.
extractAscribedType(comment, typeInContext.typed)
case t => {
- t.getMetadata(TypeNames) match {
+ val res = t.getMetadata(TypeNames)
+ res match {
case Some(
BindingsMap
.Resolution(binding @ BindingsMap.ResolvedType(_, _))
@@ -1287,7 +1288,24 @@ class IrToTruffle(
case binding: Expression.Binding => processBinding(binding)
case caseExpr: Case =>
processCase(caseExpr, subjectToInstrumentation)
- case typ: Tpe => processType(typ)
+ case asc : Tpe.Ascription =>
+ val checkNode =
+ extractAscribedType(asc.comment.orNull, asc.signature)
+ if (checkNode != null) {
+ val body = run(asc.typed, binding, subjectToInstrumentation)
+ ReadArgumentCheckNode.wrap(body, checkNode)
+ } else {
+ processType(asc)
+ }
+ case typ: Tpe =>
+ val checkNode =
+ extractAscribedType("ascribed", typ)
+ if (checkNode != null) {
+ //val body = run(typ.typed(), binding, subjectToInstrumentation)
+ ReadArgumentCheckNode.wrap(null, checkNode)
+ } else {
+ processType(typ)
+ }
case _: Empty =>
processEmpty()
case _: Comment => |
In the
I think this is an important syntactic distinction because it corresponds to a semantic distinction in whether the form causes |
I was surprised the |
Yes, the problem is that IR doesn't distinguish type declaration statements ( |
Jaroslav Tulach reports a new STANDUP for yesterday (2024-10-08): Progress: .
|
There are signatures like this is_wanted : Node -> Boolean and then the signatures like plusChecked a b =
x = a + b
x:Integer so far I have problems to differentiate them. This second case is still plusChecked a b =
x:Integer
x = a + b
x in this example, it is again
If you want, please do so. I find way easier to just process the |
Those are both currently parsed as declarations, which I think we should change (in the parser):
|
Jaroslav Tulach reports a new STANDUP for yesterday (2024-10-09): Progress: .
|
With the patch, the code runs correctly, so the patch solves the problem from a compiler perspective. From a broader tooling perspective, if the AST is wrong, and the compiler output is "right", that shows we have two bugs. #11289 fixes the immediate issue; I've opened separate issues for fixing the parser and then the compiler: |
Jaroslav Tulach reports a new STANDUP for yesterday (2024-10-10): Progress: .
|
The PR #7796 gave us the ability to check / trigger conversions of types by a type ascription
(a : Xyz)
.Apparently, this is not accepted by the parser in tail position.
yields
So
f1
is happily accepted butf2
is not.The repro itself shows how to work-around this - we just need to add an intermediate variable. Thus it's rather low priority, but still - it seems there is no reason to disallow a check in there.
The text was updated successfully, but these errors were encountered: