Skip to content

Add partial evaluation of isInstanceOf mini-phase #1275

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 7 commits into from
May 27, 2016

Conversation

felixmulder
Copy link
Contributor

In #1255 it was suggested to add a mini-phase that would simply partially evaluate calls to isInstanceOf and issue warnings/errors where appropriate.

This PR adds the ability to discern if the transformed tree came from a match or from an if as well as the proper error messages and warnings.

The following example will yield an error:

val x = Option(1)
x match {
  case Some(_: Double) => // Error
}

While the following will yield a warning:

if (x.isInstanceOf[Double]) { ...

* match
*/
def handleStaticallyKnown(tree: Select, scrutinee: Type, selector: Type, inMatch: Boolean, pos: Position): Tree =
if (!(scrutinee <:< selector) && inMatch) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it may be better to compute scrutinee <:< selector only once.

@felixmulder felixmulder force-pushed the topic/partial-eval-isInstanceOf branch from dce4f48 to b632e62 Compare May 25, 2016 12:06
@felixmulder
Copy link
Contributor Author

/rebuild

@DarkDimius DarkDimius self-assigned this May 25, 2016
else if (falseIfUnrelated && !(selector <:< scrutinee))
// selector and scrutinee are unrelated
handleFalseUnrelated(s, scrutinee, selector, inMatch)
else if (happens) tree
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there's no difference between happens and !happens

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, it was kept to showcase all cases - but I'll change it to and note this in a comment.

@felixmulder felixmulder force-pushed the topic/partial-eval-isInstanceOf branch from b632e62 to 2794657 Compare May 26, 2016 07:24
* `scrutinee.isInstanceOf[Selector]` if `scrutinee eq null`
*/
def rewrite(tree: Select, to: Boolean): Tree =
if (!to || !tree.qualifier.tpe.widen.derivesFrom(defn.AnyRefAlias))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Counterexample:

def foo = {println(1); 1}.isInstanceOf[Int]

need to check if tpd.isPure(tree.qual). If not, rewrite to Block(List(tree.qual), Literal(Constant(to))).

@felixmulder
Copy link
Contributor Author

/rebuild

if (!to || !tree.qualifier.tpe.widen.derivesFrom(defn.AnyRefAlias))
Literal(Constant(to))
else
Apply(tree.qualifier.select(defn.Object_ne), List(Literal(Constant(null))))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if tree.qualifier is not pure, it will be computed twice

@felixmulder felixmulder force-pushed the topic/partial-eval-isInstanceOf branch from 33df851 to 73f099b Compare May 26, 2016 11:21
@DarkDimius
Copy link
Contributor

LGTM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants