Skip to content

Commit 043d517

Browse files
committed
Avoid redundant errors on inferred trees
Issue well-formed errors on well-formed trees only if there are no other errors.
1 parent 9488f88 commit 043d517

File tree

3 files changed

+47
-14
lines changed

3 files changed

+47
-14
lines changed

compiler/src/dotty/tools/dotc/transform/PostTyper.scala

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,24 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisPhase
142142
tree
143143
}
144144

145+
private def processValOrDefDef(tree: Tree)(using Context): tree.type =
146+
tree match
147+
case tree: ValOrDefDef if !tree.symbol.is(Synthetic) =>
148+
checkInferredWellFormed(tree.tpt)
149+
case _ =>
150+
processMemberDef(tree)
151+
152+
private def checkInferredWellFormed(tree: Tree)(using ctx: Context): Unit = tree match
153+
case tree: TypeTree
154+
if tree.span.isZeroExtent
155+
// don't check TypeTrees with non-zero extent;
156+
// these are derived from explicit types
157+
&& !ctx.reporter.errorsReported
158+
// don't check if errors were already reported; this avoids follow-on errors
159+
// for inferred types if explicit types are already ill-formed
160+
=> Checking.checkAppliedTypesIn(tree)
161+
case _ =>
162+
145163
private def transformSelect(tree: Select, targs: List[Tree])(implicit ctx: Context): Tree = {
146164
val qual = tree.qualifier
147165
qual.symbol.moduleClass.denot match {
@@ -226,17 +244,26 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisPhase
226244
else dropInlines.transform(arg)))
227245
else
228246
tree
229-
methPart(app) match {
247+
def app1 =
248+
// reverse order of transforming args and fun. This way, we get a chance to see other
249+
// well-formedness errors before reporting errors in possible inferred type args of fun.
250+
val args1 = transform(app.args)
251+
cpy.Apply(app)(transform(app.fun), args1)
252+
methPart(app) match
230253
case Select(nu: New, nme.CONSTRUCTOR) if isCheckable(nu) =>
231254
// need to check instantiability here, because the type of the New itself
232255
// might be a type constructor.
233256
Checking.checkInstantiable(tree.tpe, nu.posd)
234-
withNoCheckNews(nu :: Nil)(super.transform(app))
257+
withNoCheckNews(nu :: Nil)(app1)
235258
case _ =>
236-
super.transform(app)
237-
}
259+
app1
260+
case UnApply(fun, implicits, patterns) =>
261+
// Reverse transform order for the same reason as in `app1` above.
262+
val patterns1 = transform(patterns)
263+
cpy.UnApply(tree)(transform(fun), transform(implicits), patterns1)
238264
case tree: TypeApply =>
239265
val tree1 @ TypeApply(fn, args) = normalizeTypeArgs(tree)
266+
args.foreach(checkInferredWellFormed)
240267
if (fn.symbol != defn.ChildAnnot.primaryConstructor)
241268
// Make an exception for ChildAnnot, which should really have AnyKind bounds
242269
Checking.checkBounds(args, fn.tpe.widen.asInstanceOf[PolyType])
@@ -262,11 +289,11 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisPhase
262289
}
263290
case tree: ValDef =>
264291
val tree1 = cpy.ValDef(tree)(rhs = normalizeErasedRhs(tree.rhs, tree.symbol))
265-
processMemberDef(super.transform(tree1))
292+
processValOrDefDef(super.transform(tree1))
266293
case tree: DefDef =>
267294
annotateContextResults(tree)
268295
val tree1 = cpy.DefDef(tree)(rhs = normalizeErasedRhs(tree.rhs, tree.symbol))
269-
processMemberDef(superAcc.wrapDefDef(tree1)(super.transform(tree1).asInstanceOf[DefDef]))
296+
processValOrDefDef(superAcc.wrapDefDef(tree1)(super.transform(tree1).asInstanceOf[DefDef]))
270297
case tree: TypeDef =>
271298
val sym = tree.symbol
272299
if (sym.isClass)
@@ -304,9 +331,6 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisPhase
304331
Checking.checkRealizable(ref.tpe, ref.posd)
305332
super.transform(tree)
306333
case tree: TypeTree =>
307-
if tree.span.isZeroExtent then
308-
// Don't check TypeTrees with non-zero extent; these are derived from explicit types
309-
Checking.checkAppliedTypesIn(tree)
310334
tree.withType(
311335
tree.tpe match {
312336
case AnnotatedType(tpe, annot) => AnnotatedType(tpe, transformAnnot(annot))

tests/neg/i4382.check

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,24 @@
1-
-- Error: tests/neg/i4382.scala:3:10 -----------------------------------------------------------------------------------
1+
-- [E043] Type Error: tests/neg/i4382.scala:3:10 -----------------------------------------------------------------------
22
3 | def v1: Id[_] = ??? // error
33
| ^^^^^
44
| unreducible application of higher-kinded type App.Id to wildcard arguments
5-
-- Error: tests/neg/i4382.scala:6:10 -----------------------------------------------------------------------------------
5+
6+
longer explanation available when compiling with `-explain`
7+
-- [E043] Type Error: tests/neg/i4382.scala:6:10 -----------------------------------------------------------------------
68
6 | def v2: HkL[_] = ??? // error
79
| ^^^^^^
810
| unreducible application of higher-kinded type App.HkL to wildcard arguments
9-
-- Error: tests/neg/i4382.scala:9:10 -----------------------------------------------------------------------------------
11+
12+
longer explanation available when compiling with `-explain`
13+
-- [E043] Type Error: tests/neg/i4382.scala:9:10 -----------------------------------------------------------------------
1014
9 | def v3: HkU[_] = ??? // error
1115
| ^^^^^^
1216
| unreducible application of higher-kinded type App.HkU to wildcard arguments
13-
-- Error: tests/neg/i4382.scala:12:10 ----------------------------------------------------------------------------------
17+
18+
longer explanation available when compiling with `-explain`
19+
-- [E043] Type Error: tests/neg/i4382.scala:12:10 ----------------------------------------------------------------------
1420
12 | def v4: HkAbs[_] = ??? // error
1521
| ^^^^^^^^
1622
| unreducible application of higher-kinded type App.HkAbs to wildcard arguments
23+
24+
longer explanation available when compiling with `-explain`

tests/neg/i5302.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
type L[X]
2-
def foo = { class A; null.asInstanceOf[L[A]] } // error // error
2+
def foo = { class A; null.asInstanceOf[L[A]] } // error
3+
def bar(x: L[_]) = x // error

0 commit comments

Comments
 (0)