SI-1503 don't assume unsound type for ident/literal patterns #3559

Merged
merged 1 commit into from Feb 23, 2014

Projects

None yet

2 participants

@adriaanm
Member

The fix only kicks in under -Xfuture. We also warn under -Xlint.

What type should a variable bound to the value matched by a pattern have?
To avoid CCEs, it should be a type that's implied by the matching
semantics of the pattern.

Usually, the type implied by a pattern matching a certain value
is the pattern's type, because pattern matching implies instance-of checks.

However, Stable Identifier and Literal patterns are matched using ==,
which does not imply a type for the binder that binds the matched value.

The change in type checking due to this fix is that programs that used to crash with a CCE
(because we blindly cast to the type of the pattern, which a == check does not imply)
now get a weaker type instead (and no cast). They may still type check, or they may not.

To compensate for this fix, change case x@Foo => x to case x: Foo.type => x,
if it's important that x have type Foo.type.

See also:

  • SI-4577: matching of singleton type patterns uses eq,
    not == (so that the types are not a lie).
  • SI-5024: patmat strips unused bindings, but affects semantics
@adriaanm
Member

Review by @gkossakowski

@adriaanm adriaanm SI-1503 don't assume unsound type for ident/literal patterns
The fix only kicks in under -Xfuture. We also warn under -Xlint.

What type should a variable bound to the value matched by a pattern have?
To avoid CCEs, it should be a type that's implied by the matching
semantics of the pattern.

Usually, the type implied by a pattern matching a certain value
is the pattern's type, because pattern matching implies instance-of checks.

However, Stable Identifier and Literal patterns are matched using `==`,
which does not imply a type for the binder that binds the matched value.

The change in type checking due to this fix is that programs that used to crash with a CCE
(because we blindly cast to the type of the pattern, which a `==` check does not imply)
now get a weaker type instead (and no cast). They may still type check, or they may not.

To compensate for this fix, change `case x@Foo => x` to `case x: Foo.type => x`,
if it's important that `x` have type `Foo.type`.

See also:
- SI-4577: matching of singleton type patterns uses `eq`,
  not `==` (so that the types are not a lie).
- SI-5024: patmat strips unused bindings, but affects semantics
c001b88
@adriaanm adriaanm added tested and removed needs-attention labels Feb 19, 2014
@adriaanm
Member
@gkossakowski
Member

LGTM

@gkossakowski gkossakowski merged commit 5c84255 into scala:master Feb 23, 2014

1 check passed

default pr-scala Took 72 min.
Details
@adriaanm adriaanm deleted the adriaanm:t1503 branch Mar 10, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment