Skip to content

Backport "Improve parameter type inference error messaging" to LTS #19119

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

Merged
merged 1 commit into from
Dec 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions compiler/src/dotty/tools/dotc/reporting/ErrorMessageID.scala
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,14 @@ enum ErrorMessageID(val isActive: Boolean = true) extends java.lang.Enum[ErrorMe
case AmbiguousExtensionMethodID // errorNumber 180
case UnqualifiedCallToAnyRefMethodID // errorNumber: 181
case NotConstantID // errorNumber: 182
case ClosureCannotHaveInternalParameterDependenciesID // errorNumber: 183
case MatchTypeNoCasesID // errorNumber: 184
case UnimportedAndImportedID // errorNumber: 185
case ImplausiblePatternWarningID // errorNumber: 186
case SynchronizedCallOnBoxedClassID // errorNumber: 187
case VarArgsParamCannotBeGivenID // errorNumber: 188
case ExtractorNotFoundID // errorNumber: 189
case PureUnitExpressionID // errorNumber: 190

def errorNumber = ordinal - 1

Expand Down
18 changes: 11 additions & 7 deletions compiler/src/dotty/tools/dotc/reporting/messages.scala
Original file line number Diff line number Diff line change
Expand Up @@ -160,23 +160,27 @@ extends SyntaxMsg(CaseClassMissingParamListID) {

class AnonymousFunctionMissingParamType(param: untpd.ValDef,
tree: untpd.Function,
pt: Type)
inferredType: Type,
expectedType: Type,
)
(using Context)
extends TypeMsg(AnonymousFunctionMissingParamTypeID) {
def msg(using Context) = {
val ofFun =
if param.name.is(WildcardParamName)
|| (MethodType.syntheticParamNames(tree.args.length + 1) contains param.name)
then i" of expanded function:\n$tree"
then i"\n\nIn expanded function:\n$tree"
else ""

val inferred =
if (pt == WildcardType) ""
else i"\nWhat I could infer was: $pt"
if (inferredType == WildcardType) ""
else i"\n\nPartially inferred type for the parameter: $inferredType"

i"""Missing parameter type
|
|I could not infer the type of the parameter ${param.name}$ofFun.$inferred"""
val expected =
if (expectedType == WildcardType) ""
else i"\n\nExpected type for the whole anonymous function: $expectedType"

i"Could not infer type for parameter ${param.name} of anonymous function$ofFun$inferred$expected"
}

def explain(using Context) = ""
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/typer/Typer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1612,7 +1612,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
else
inferredFromTarget(param, formal, calleeType, isErased, paramIndex).orElse(
if knownFormal then formal0
else errorType(AnonymousFunctionMissingParamType(param, tree, formal), param.srcPos)
else errorType(AnonymousFunctionMissingParamType(param, tree, inferredType = formal, expectedType = pt), param.srcPos)
)
val paramTpt = untpd.TypedSplice(
(if knownFormal then InferredTypeTree() else untpd.TypeTree())
Expand Down
14 changes: 8 additions & 6 deletions tests/neg/i11350.check
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
-- [E081] Type Error: tests/neg/i11350.scala:1:39 ----------------------------------------------------------------------
1 |class A1[T](action: A1[T] ?=> String = "") // error
| ^
| Missing parameter type
| Could not infer type for parameter evidence$1 of anonymous function
|
| I could not infer the type of the parameter evidence$1.
| What I could infer was: A1[<?>]
| Partially inferred type for the parameter: A1[<?>]
|
| Expected type for the whole anonymous function: (A1[<?>]) ?=> String
-- [E081] Type Error: tests/neg/i11350.scala:2:39 ----------------------------------------------------------------------
2 |class A2[T](action: A1[T] ?=> String = summon[A1[T]]) // error
| ^
| Missing parameter type
| Could not infer type for parameter evidence$2 of anonymous function
|
| Partially inferred type for the parameter: A1[<?>]
|
| I could not infer the type of the parameter evidence$2.
| What I could infer was: A1[<?>]
| Expected type for the whole anonymous function: (A1[<?>]) ?=> String
8 changes: 5 additions & 3 deletions tests/neg/i11561.check
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
-- [E081] Type Error: tests/neg/i11561.scala:2:32 ----------------------------------------------------------------------
2 | val updateText1 = copy(text = _) // error
| ^
| Missing parameter type
| Could not infer type for parameter _$1 of anonymous function
|
| I could not infer the type of the parameter _$1 of expanded function:
| _$1 => State.this.text = _$1.
| In expanded function:
| _$1 => State.this.text = _$1
|
| Expected type for the whole anonymous function: String
-- [E052] Type Error: tests/neg/i11561.scala:3:30 ----------------------------------------------------------------------
3 | val updateText2 = copy(text = (_: String)) // error
| ^^^^^^^^^^^^^^^^^^
Expand Down