File tree 7 files changed +64
-11
lines changed
compiler/src/dotty/tools/dotc/typer 7 files changed +64
-11
lines changed Original file line number Diff line number Diff line change @@ -3762,7 +3762,19 @@ class Typer extends Namer
3762
3762
TypeComparer .constrainPatternType(tree.tpe, pt)
3763
3763
}
3764
3764
3765
- if tree.symbol.is(Module ) && ! (tree.tpe <:< pt) then
3765
+ // approximate type params with bounds
3766
+ def approx = new ApproximatingTypeMap {
3767
+ def apply (tp : Type ) = tp.dealias match
3768
+ case tp : TypeRef if ! tp.symbol.isClass =>
3769
+ expandBounds(tp.info.bounds)
3770
+ case _ =>
3771
+ mapOver(tp)
3772
+ }
3773
+
3774
+ if tree.symbol.is(Module )
3775
+ && ! (tree.tpe frozen_<:< pt) // fast track
3776
+ && ! (tree.tpe frozen_<:< approx(pt))
3777
+ then
3766
3778
// We could check whether `equals` is overriden.
3767
3779
// Reasons for not doing so:
3768
3780
// - it complicates the protocol
Original file line number Diff line number Diff line change
1
+ trait Is [A ]
2
+ case object IsInt extends Is [Int ]
3
+ case object IsString extends Is [String ]
4
+ case class C [A ](is : Is [A ], value : A )
5
+
6
+ @ main
7
+ def Test = {
8
+ val c_string : C [String ] = C (IsString , " name" )
9
+ val c_any : C [_] = c_string
10
+ val any : Any = c_string
11
+
12
+ // Case 1: error
13
+ c_string match {
14
+ case C (IsInt , _) => println(s " An Int " ) // error
15
+ case C (IsString , s) => println(s " A String with length ${s.length}" )
16
+ case _ => println(" No match" )
17
+ }
18
+
19
+ // Case 2: Should match the second case and print the length of the string
20
+ c_any match {
21
+ case C (IsInt , i) if i < 10 => println(s " An Int less than 10 " )
22
+ case C (IsString , s) => println(s " A String with length ${s.length}" )
23
+ case _ => println(" No match" )
24
+ }
25
+
26
+ // Case 3: Same as above; should match the second case and print the length of the string
27
+ any match {
28
+ case C (IsInt , i) if i < 10 => println(s " An Int less than 10 " )
29
+ case C (IsString , s) => println(s " A String with length ${s.length}" )
30
+ case _ => println(" No match" )
31
+ }
32
+ }
Original file line number Diff line number Diff line change
1
+ sealed trait Exp [T ]
2
+ case class IntExp (x : Int ) extends Exp [Int ]
3
+ case class StrExp (x : String ) extends Exp [String ]
4
+ object UnitExp extends Exp [Unit ]
5
+
6
+ class Foo [U <: Int , T <: U ] {
7
+ def bar [A <: T ](x : Exp [A ]): Unit = x match
8
+ case IntExp (x) =>
9
+ case StrExp (x) =>
10
+ case UnitExp =>
11
+ }
Original file line number Diff line number Diff line change 1
1
object autoTupling {
2
2
3
- val x = Some (1 , 2 )
3
+ val x : Option [( Int , Int )] = Some (1 , 2 )
4
4
5
5
x match {
6
6
case Some (a, b) => a + b
Original file line number Diff line number Diff line change 1
- val foo : Int => Int = Some (7 ) match
1
+ val foo : Int => Int = Option (7 ) match
2
2
case Some (y) => x => y
3
3
case None => identity[Int ]
Original file line number Diff line number Diff line change 1
1
A String with length 4
2
2
A String with length 4
3
- A String with length 4
Original file line number Diff line number Diff line change @@ -9,13 +9,12 @@ def Test = {
9
9
val c_any : C [_] = c_string
10
10
val any : Any = c_string
11
11
12
- // Case 1: no error
13
- // `IsInt.equals` might be overridden to match a value of `C[String]`
14
- c_string match {
15
- case C (IsInt , _) => println(s " An Int " ) // Can't possibly happen!
16
- case C (IsString , s) => println(s " A String with length ${s.length}" )
17
- case _ => println(" No match" )
18
- }
12
+ // Case 1: error, tested in tests/neg/i5077.scala
13
+ // c_string match {
14
+ // case C(IsInt, _) => println(s"An Int") // Can't possibly happen!
15
+ // case C(IsString, s) => println(s"A String with length ${s.length}")
16
+ // case _ => println("No match")
17
+ // }
19
18
20
19
// Case 2: Should match the second case and print the length of the string
21
20
c_any match {
You can’t perform that action at this time.
0 commit comments