Skip to content

Avoid creating cyclic types when reporting errors in selectionType #12223

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 2 commits into from
May 3, 2021
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
6 changes: 3 additions & 3 deletions compiler/src/dotty/tools/dotc/reporting/Message.scala
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package dotty.tools
package dotc
package reporting

import scala.annotation.threadUnsafe
import util.SourcePosition

object Message {
Expand Down Expand Up @@ -85,10 +85,10 @@ abstract class Message(val errorId: ErrorMessageID) { self =>
def rawMessage = message

/** The message to report. <nonsensical> tags are filtered out */
lazy val message: String = dropNonSensical(msg + msgSuffix)
@threadUnsafe lazy val message: String = dropNonSensical(msg + msgSuffix)

/** The explanation to report. <nonsensical> tags are filtered out */
lazy val explanation: String = dropNonSensical(explain)
@threadUnsafe lazy val explanation: String = dropNonSensical(explain)

/** A message is non-sensical if it contains references to <nonsensical>
* tags. Such tags are inserted by the error diagnostic framework if a
Expand Down
15 changes: 9 additions & 6 deletions compiler/src/dotty/tools/dotc/typer/TypeAssigner.scala
Original file line number Diff line number Diff line change
Expand Up @@ -117,12 +117,15 @@ trait TypeAssigner {

/** The type of the selection `tree`, where `qual1` is the typed qualifier part. */
def selectionType(tree: untpd.RefTree, qual1: Tree)(using Context): Type =
var qualType = qual1.tpe.widenIfUnstable
if !qualType.hasSimpleKind && tree.name != nme.CONSTRUCTOR then
// constructors are selected on typeconstructor, type arguments are passed afterwards
qualType = errorType(em"$qualType takes type parameters", qual1.srcPos)
else if !qualType.isInstanceOf[TermType] then
qualType = errorType(em"$qualType is illegal as a selection prefix", qual1.srcPos)
val qualType0 = qual1.tpe.widenIfUnstable
val qualType =
if !qualType0.hasSimpleKind && tree.name != nme.CONSTRUCTOR then
// constructors are selected on typeconstructor, type arguments are passed afterwards
errorType(em"$qualType0 takes type parameters", qual1.srcPos)
else if !qualType0.isInstanceOf[TermType] && !qualType0.isError then
errorType(em"$qualType0 is illegal as a selection prefix", qual1.srcPos)
else
qualType0

def arrayElemType = qual1.tpe.widen match
case JavaArrayType(elemtp) => elemtp
Expand Down
3 changes: 3 additions & 0 deletions tests/neg/i12220.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
val a: List[Any] = List(List(1,2), List(3,4))
val _ = for(b <- a ; c <- b.asInstanceOf[List]) { println(c) } // error