-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Fix #4653: check method return type is value type #4844
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
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hello, and thank you for opening this PR! 🎉
All contributors have signed the CLA, thank you! ❤️
Have an awesome day! ☀️
The following code: trait T {
type S
}
class C {
class D[X](val t: T) {
def bar: t.S = ???
}
val foo: D = new D[Int](???) // error
foo.bar
} gets the following error: -- [E056] Syntax Error: examples/abc.scala:10:11 -------------------------------
10 | val foo: D = new D[Int](???) // error
| ^
| missing type parameter for C.this.D
one error found @Medowhill could you please try if we can produce similar error messages? |
trait T {
type S
}
class C {
class D[X](val t: T) {
def bar: t.S = ???
}
def f(foo: => D) = foo.bar
} It produces the same crash at both master branch and fixed version. It seems handling only method return type is not a complete solution. I'll find a fix works for both value and method. |
if (tp.isValueType || (tp match { | ||
case ExprType(tp1) => tp1.isValueType | ||
case _ => false | ||
})) tp else ErrorType("A type of a value or a return type of a method should be a value type.")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's more succinct to write tp.widenExpr.isValueType
here. I'm curious which test fails without the widening?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll fix it. Thank you!
When a method has a by-name parameter, typing ValDef
of the parameter results ExprType
. Therefore, we should allow ExprType
, whose result type is ValueType
, in addition to ValueType
.
paramFn(typedAheadType(mdef.tpt, tptProto).tpe) | ||
val tp = typedAheadType(mdef.tpt, tptProto).tpe | ||
paramFn(if (tp.widenExpr.isValueType) tp | ||
else ErrorType("A type of a value or a return type of a method should be a value type.")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about reuse checkSimpleKinded
? This way, we don't need to define a new error message and the logic can be reused.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
diff --git a/compiler/src/dotty/tools/dotc/typer/Namer.scala b/compiler/src/dotty/tools/dotc/typer/Namer.scala
index 8de871adbc3..2933c3dc92a 100644
--- a/compiler/src/dotty/tools/dotc/typer/Namer.scala
+++ b/compiler/src/dotty/tools/dotc/typer/Namer.scala
@@ -1153,9 +1153,7 @@ class Namer { typer: Typer =>
case _ =>
WildcardType
}
- val tp = typedAheadType(mdef.tpt, tptProto).tpe
- paramFn(if (tp.widenExpr.isValueType) tp
- else ErrorType("A type of a value or a return type of a method should be a value type."))
+ paramFn(checkSimpleKinded(typedAheadType(mdef.tpt, tptProto)).tpe)
}
It looks clearer. Thank you!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great, LGTM 👍
Could you please squash the history to one commit? Thanks.
No description provided.