diff options
author | Martin Odersky <odersky@gmail.com> | 2017-02-21 09:28:22 +0100 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2017-02-21 09:28:30 +0100 |
commit | 5f9e569926728e7f591a26729efa7700387aeb22 (patch) | |
tree | 435f8bc107e8def412ce00aef5fbc4d633ac1f53 /compiler/src/dotty/tools/dotc/typer | |
parent | f467be62da8978e506f58b702b84e74ef7ce09de (diff) | |
download | dotty-5f9e569926728e7f591a26729efa7700387aeb22.tar.gz dotty-5f9e569926728e7f591a26729efa7700387aeb22.tar.bz2 dotty-5f9e569926728e7f591a26729efa7700387aeb22.zip |
Don't inline when errors are detected
Inlining is only well-defined if the body to inline does not
have any errors. We therefore check for errors before we
perform any transformation of trees related to inlining.
The error check is global, i.e. we stop on any error
not just on errors in the code to be inlined. This is a safe
approximation, of course.
Diffstat (limited to 'compiler/src/dotty/tools/dotc/typer')
-rw-r--r-- | compiler/src/dotty/tools/dotc/typer/Inliner.scala | 11 | ||||
-rw-r--r-- | compiler/src/dotty/tools/dotc/typer/Typer.scala | 3 |
2 files changed, 9 insertions, 5 deletions
diff --git a/compiler/src/dotty/tools/dotc/typer/Inliner.scala b/compiler/src/dotty/tools/dotc/typer/Inliner.scala index cfc0003c6..3fa39edd5 100644 --- a/compiler/src/dotty/tools/dotc/typer/Inliner.scala +++ b/compiler/src/dotty/tools/dotc/typer/Inliner.scala @@ -27,7 +27,7 @@ import transform.TypeUtils._ object Inliner { import tpd._ - /** Adds accessors accessors for all non-public term members accessed + /** Adds accessors for all non-public term members accessed * from `tree`. Non-public type members are currently left as they are. * This means that references to a private type will lead to typing failures * on the code when it is inlined. Less than ideal, but hard to do better (see below). @@ -190,7 +190,8 @@ object Inliner { val inlineCtx = ctx sym.updateAnnotation(LazyBodyAnnotation { _ => implicit val ctx = inlineCtx - ctx.withNoError(treeExpr(ctx))(makeInlineable) + val body = treeExpr(ctx) + if (ctx.reporter.hasErrors) body else makeInlineable(body) }) } } @@ -233,8 +234,10 @@ object Inliner { * and body that replace it. */ def inlineCall(tree: Tree, pt: Type)(implicit ctx: Context): Tree = - if (enclosingInlineds.length < ctx.settings.xmaxInlines.value) - new Inliner(tree, bodyToInline(tree.symbol)).inlined(pt) + if (enclosingInlineds.length < ctx.settings.xmaxInlines.value) { + val body = bodyToInline(tree.symbol) // can typecheck the tree and thereby produce errors + if (ctx.reporter.hasErrors) tree else new Inliner(tree, body).inlined(pt) + } else errorTree( tree, i"""|Maximal number of successive inlines (${ctx.settings.xmaxInlines.value}) exceeded, diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index 498fd001b..26f7bc65b 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -1964,7 +1964,8 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit if (Inliner.hasBodyToInline(tree.symbol) && !ctx.owner.ownersIterator.exists(_.isInlineMethod) && !ctx.settings.YnoInline.value && - !ctx.isAfterTyper) + !ctx.isAfterTyper && + !ctx.reporter.hasErrors) adapt(Inliner.inlineCall(tree, pt), pt) else if (ctx.typeComparer.GADTused && pt.isValueType) // Insert an explicit cast, so that -Ycheck in later phases succeeds. |